tccpp: Fix corner case of fnlike macro invocation
Arg substitution leaves placeholder marker in the stream for empty arguments. Those need to be skipped when searching for a fnlike macro invocation in the replacement list itself. See testcase.
This commit is contained in:
		
							parent
							
								
									536ed76d5a
								
							
						
					
					
						commit
						328b826e8a
					
				
					 3 changed files with 22 additions and 2 deletions
				
			
		
							
								
								
									
										6
									
								
								tccpp.c
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								tccpp.c
									
										
									
									
									
								
							|  | @ -3023,7 +3023,7 @@ static int next_argstream(Sym **nested_list, int can_read_stream, TokenString *w | |||
|         if (macro_ptr) { | ||||
|             p = macro_ptr, t = *p; | ||||
|             if (ws_str) { | ||||
|                 while (is_space(t) || TOK_LINEFEED == t) | ||||
|                 while (is_space(t) || TOK_LINEFEED == t || TOK_PLCHLDR == t) | ||||
|                     tok_str_add(ws_str, t), t = *++p; | ||||
|             } | ||||
|             if (t == 0 && can_read_stream) { | ||||
|  | @ -3152,7 +3152,9 @@ static int macro_subst_tok( | |||
|             } else { | ||||
|                 tok_str_free_str(ws_str.str); | ||||
|             } | ||||
|             next_nomacro(); /* eat '(' */ | ||||
| 	    do { | ||||
| 		next_nomacro(); /* eat '(' */ | ||||
| 	    } while (tok == TOK_PLCHLDR); | ||||
| 
 | ||||
|             /* argument macro */ | ||||
|             args = NULL; | ||||
|  |  | |||
							
								
								
									
										15
									
								
								tests/pp/18.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tests/pp/18.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| #define M_RETI_ARG27(x,y,z,aa, ...)    aa | ||||
| #define M_RET_ARG27(...)        M_RETI_ARG27(__VA_ARGS__) | ||||
| #define M_COMMA_P(...)          M_RET_ARG27(__VA_ARGS__, 1, 1, 0, useless) | ||||
| #define M_EMPTYI_DETECT(...)    0, 1, | ||||
| #define M_EMPTYI_P_C1(...)      M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__ () ) | ||||
| #define EX | ||||
| #define empty(x) | ||||
| #define fnlike(x) yeah x | ||||
| /* If the following macro is called with empty arg (X183), the use
 | ||||
|    of 'x' between fnlike and '(' doesn't hinder the recognition of this | ||||
|    being a further fnlike macro invocation.  */ | ||||
| #define usefnlike(x) fnlike x (x) | ||||
| X181 M_EMPTYI_P_C1() | ||||
| X182 M_EMPTYI_P_C1(x) | ||||
| X183 usefnlike() | ||||
							
								
								
									
										3
									
								
								tests/pp/18.expect
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								tests/pp/18.expect
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| X181 1 | ||||
| X182 0 | ||||
| X183 yeah | ||||
		Loading…
	
	Add table
		
		Reference in a new issue