Unsupported #pragma within argument lists of function-like macro invocation.

This commit is contained in:
acqn
2022-08-06 16:56:28 +08:00
parent 251e984ba8
commit 0a051a4dee

View File

@@ -84,7 +84,6 @@ static StrBuf* OLine; /* Buffer for #pragma output */
/* Newlines to be added to preprocessed text */ /* Newlines to be added to preprocessed text */
static int PendingNewLines; static int PendingNewLines;
static int FileChanged; static int FileChanged;
static int LeadingWhitespace;
/* Structure used when expanding macros */ /* Structure used when expanding macros */
typedef struct MacroExp MacroExp; typedef struct MacroExp MacroExp;
@@ -107,7 +106,7 @@ static void TranslationPhase3 (StrBuf* Source, StrBuf* Target);
** non-newline whitespace sequences. ** non-newline whitespace sequences.
*/ */
static int ParseDirectives (void); static int ParseDirectives (int InArgList);
/* Handle directives. Return 1 if there are directives parsed, -1 if new lines /* Handle directives. Return 1 if there are directives parsed, -1 if new lines
** are read, otherwise 0. ** are read, otherwise 0.
*/ */
@@ -544,19 +543,13 @@ static void ReadMacroArgs (MacroExp* E, int MultiLine)
if (MultiLine && CurC == '#') { if (MultiLine && CurC == '#') {
int Newlines = 0; int Newlines = 0;
SB_Cut (OLine, SB_GetLen (OLine) - LeadingWhitespace);
if (OldPendingNewLines == 0 && SB_NotEmpty (Line) && SB_LookAtLast (OLine) != '\n') {
OldPendingNewLines = 1;
}
while (CurC == '#') { while (CurC == '#') {
Newlines += PendingNewLines - OldPendingNewLines; Newlines += PendingNewLines - OldPendingNewLines;
PendingNewLines = OldPendingNewLines; PendingNewLines = OldPendingNewLines;
OldPendingNewLines = 0; OldPendingNewLines = 0;
Skipped = ParseDirectives () || Skipped; Skipped = ParseDirectives (1) || Skipped;
Skipped = SkipWhitespace (MultiLine) || Skipped; Skipped = SkipWhitespace (MultiLine) || Skipped;
} }
AppendIndent (OLine, LeadingWhitespace);
LeadingWhitespace = 0;
PendingNewLines += Newlines; PendingNewLines += Newlines;
} }
if (Skipped && SB_NotEmpty (&Arg)) { if (Skipped && SB_NotEmpty (&Arg)) {
@@ -1152,10 +1145,10 @@ static void MacroReplacement (StrBuf* Source, StrBuf* Target, int MultiLine)
if (CurC == '#') { if (CurC == '#') {
if (OLine == 0) { if (OLine == 0) {
OLine = Target; OLine = Target;
ParseDirectives (); ParseDirectives (0);
OLine = 0; OLine = 0;
} else { } else {
ParseDirectives (); ParseDirectives (0);
} }
} }
/* Add the source info to preprocessor output if needed */ /* Add the source info to preprocessor output if needed */
@@ -1394,25 +1387,20 @@ static void DoPragma (void)
{ {
StrBuf* PragmaLine = OLine; StrBuf* PragmaLine = OLine;
/* Macro-replace a single line */ PRECONDITION (PragmaLine != 0);
SB_Clear (MLine);
ProcessSingleLine (Line, MLine, 0, 0);
/* Convert the directive into the operator */
if (OLine == 0) {
SB_Clear (Line);
PragmaLine = Line;
}
/* Add the source info to preprocessor output if needed */ /* Add the source info to preprocessor output if needed */
AddPreLine (PragmaLine); AddPreLine (PragmaLine);
/* Macro-replace a single line */
SB_Clear (MLine);
ProcessSingleLine (Line, MLine, 0, 0);
/* Convert #pragma to _Pragma () */ /* Convert #pragma to _Pragma () */
SB_AppendStr (PragmaLine, "_Pragma ("); SB_AppendStr (PragmaLine, "_Pragma (");
SB_Reset (MLine); SB_Reset (MLine);
Stringize (MLine, PragmaLine); Stringize (MLine, PragmaLine);
SB_AppendChar (PragmaLine, ')'); SB_AppendChar (PragmaLine, ')');
SB_AppendChar (PragmaLine, '\n');
/* End this line */ /* End this line */
SB_SetIndex (PragmaLine, SB_GetLen (PragmaLine)); SB_SetIndex (PragmaLine, SB_GetLen (PragmaLine));
@@ -1454,19 +1442,17 @@ static void DoWarning (void)
static int ParseDirectives (void) static int ParseDirectives (int InArgList)
/* Handle directives. Return howmany newlines are parsed. */ /* Handle directives. Return 1 if any whitespace or newlines are parsed. */
{ {
int NewLines = 0; int PPSkip = 0;
int Skip;
ident Directive; ident Directive;
/* Skip white space at the beginning of the line */ /* Skip white space at the beginning of the first line */
SkipWhitespace (0); int Whitespace = SkipWhitespace (0);
/* Check for stuff to skip */ /* Check for stuff to skip */
Skip = 0; while (CurC == '\0' || CurC == '#' || PPSkip) {
while (CurC == '\0' || CurC == '#' || Skip) {
/* Check for preprocessor lines lines */ /* Check for preprocessor lines lines */
if (CurC == '#') { if (CurC == '#') {
@@ -1477,7 +1463,7 @@ static int ParseDirectives (void)
continue; continue;
} }
if (!IsSym (Directive)) { if (!IsSym (Directive)) {
if (!Skip) { if (!PPSkip) {
PPError ("Preprocessor directive expected"); PPError ("Preprocessor directive expected");
} }
ClearLine (); ClearLine ();
@@ -1485,7 +1471,7 @@ static int ParseDirectives (void)
switch (FindPPToken (Directive)) { switch (FindPPToken (Directive)) {
case PP_DEFINE: case PP_DEFINE:
if (!Skip) { if (!PPSkip) {
DefineMacro (); DefineMacro ();
} }
break; break;
@@ -1495,10 +1481,10 @@ static int ParseDirectives (void)
if ((PPStack->Stack[PPStack->Index] & IFCOND_ELSE) == 0) { if ((PPStack->Stack[PPStack->Index] & IFCOND_ELSE) == 0) {
/* Handle as #else/#if combination */ /* Handle as #else/#if combination */
if ((PPStack->Stack[PPStack->Index] & IFCOND_SKIP) == 0) { if ((PPStack->Stack[PPStack->Index] & IFCOND_SKIP) == 0) {
Skip = !Skip; PPSkip = !PPSkip;
} }
PPStack->Stack[PPStack->Index] |= IFCOND_ELSE; PPStack->Stack[PPStack->Index] |= IFCOND_ELSE;
Skip = DoIf (Skip); PPSkip = DoIf (PPSkip);
/* #elif doesn't need a terminator */ /* #elif doesn't need a terminator */
PPStack->Stack[PPStack->Index] &= ~IFCOND_NEEDTERM; PPStack->Stack[PPStack->Index] &= ~IFCOND_NEEDTERM;
@@ -1514,7 +1500,7 @@ static int ParseDirectives (void)
if (PPStack->Index >= 0) { if (PPStack->Index >= 0) {
if ((PPStack->Stack[PPStack->Index] & IFCOND_ELSE) == 0) { if ((PPStack->Stack[PPStack->Index] & IFCOND_ELSE) == 0) {
if ((PPStack->Stack[PPStack->Index] & IFCOND_SKIP) == 0) { if ((PPStack->Stack[PPStack->Index] & IFCOND_SKIP) == 0) {
Skip = !Skip; PPSkip = !PPSkip;
} }
PPStack->Stack[PPStack->Index] |= IFCOND_ELSE; PPStack->Stack[PPStack->Index] |= IFCOND_ELSE;
@@ -1542,7 +1528,7 @@ static int ParseDirectives (void)
CHECK (PPStack->Index >= 0); CHECK (PPStack->Index >= 0);
/* Remove the clause that needs a terminator */ /* Remove the clause that needs a terminator */
Skip = (PPStack->Stack[PPStack->Index--] & IFCOND_SKIP) != 0; PPSkip = (PPStack->Stack[PPStack->Index--] & IFCOND_SKIP) != 0;
/* Check for extra tokens */ /* Check for extra tokens */
CheckExtraTokens ("endif"); CheckExtraTokens ("endif");
@@ -1552,45 +1538,48 @@ static int ParseDirectives (void)
break; break;
case PP_ERROR: case PP_ERROR:
if (!Skip) { if (!PPSkip) {
DoError (); DoError ();
} }
break; break;
case PP_IF: case PP_IF:
Skip = DoIf (Skip); PPSkip = DoIf (PPSkip);
break; break;
case PP_IFDEF: case PP_IFDEF:
Skip = DoIfDef (Skip, 1); PPSkip = DoIfDef (PPSkip, 1);
break; break;
case PP_IFNDEF: case PP_IFNDEF:
Skip = DoIfDef (Skip, 0); PPSkip = DoIfDef (PPSkip, 0);
break; break;
case PP_INCLUDE: case PP_INCLUDE:
if (!Skip) { if (!PPSkip) {
DoInclude (); DoInclude ();
} }
break; break;
case PP_LINE: case PP_LINE:
/* Should do something in C99 at least, but we ignore it */ /* Should do something in C99 at least, but we ignore it */
if (!Skip) { if (!PPSkip) {
ClearLine (); ClearLine ();
} }
break; break;
case PP_PRAGMA: case PP_PRAGMA:
if (!Skip) { if (!PPSkip) {
DoPragma (); if (!InArgList) {
--NewLines; DoPragma ();
} else {
PPError ("Embedded #pragma directive within macro arguments is unsupported");
}
} }
break; break;
case PP_UNDEF: case PP_UNDEF:
if (!Skip) { if (!PPSkip) {
DoUndef (); DoUndef ();
} }
break; break;
@@ -1598,11 +1587,11 @@ static int ParseDirectives (void)
case PP_WARNING: case PP_WARNING:
/* #warning is a non standard extension */ /* #warning is a non standard extension */
if (IS_Get (&Standard) > STD_C99) { if (IS_Get (&Standard) > STD_C99) {
if (!Skip) { if (!PPSkip) {
DoWarning (); DoWarning ();
} }
} else { } else {
if (!Skip) { if (!PPSkip) {
PPError ("Preprocessor directive expected"); PPError ("Preprocessor directive expected");
} }
ClearLine (); ClearLine ();
@@ -1610,7 +1599,7 @@ static int ParseDirectives (void)
break; break;
default: default:
if (!Skip) { if (!PPSkip) {
PPError ("Preprocessor directive expected"); PPError ("Preprocessor directive expected");
} }
ClearLine (); ClearLine ();
@@ -1621,12 +1610,11 @@ static int ParseDirectives (void)
if (NextLine () == 0) { if (NextLine () == 0) {
break; break;
} }
++NewLines; ++PendingNewLines;
SkipWhitespace (0); Whitespace = SkipWhitespace (0) || Whitespace;
} }
PendingNewLines += NewLines; return Whitespace != 0;
return NewLines;
} }
@@ -1641,15 +1629,14 @@ void Preprocess (void)
/* Parse any directives */ /* Parse any directives */
OLine = PLine; OLine = PLine;
ParseDirectives (); ParseDirectives (0);
OLine = 0; OLine = 0;
/* Add the source info to preprocessor output if needed */ /* Add the source info to preprocessor output if needed */
AddPreLine (PLine); AddPreLine (PLine);
/* Add leading whitespace to prettify preprocessor output */ /* Add leading whitespace to prettify preprocessor output */
LeadingWhitespace = SB_GetIndex (Line); AppendIndent (PLine, SB_GetIndex (Line));
AppendIndent (PLine, LeadingWhitespace);
/* Expand macros if any */ /* Expand macros if any */
MacroReplacement (Line, PLine, 1); MacroReplacement (Line, PLine, 1);