]> granicus.if.org Git - clang/commitdiff
Preprocessor: Recover instead of mutating a token in ExpandBuiltinMacro
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 15 Dec 2014 09:03:58 +0000 (09:03 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 15 Dec 2014 09:03:58 +0000 (09:03 +0000)
We would CreateString on arbitrary garbage instead of just skipping to
the end of the builtin macro.  Eventually, this would cause us to crash
because we would end up replacing the contents of a character token with
a numeric literal.

This fixes PR21825.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@224238 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Lex/PPMacroExpansion.cpp
test/Preprocessor/feature_tests.c

index d9a7f39913a1ac9e5a85986ff6dc7a81097802d0..cd05d06633f244e8d2f1658024a80186f286feb6 100644 (file)
@@ -1415,6 +1415,10 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
         if (IsScopeValid && Tok.is(tok::r_paren))
           IsValid = true;
       }
+      // Eat tokens until ')'.
+      while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eod) &&
+             Tok.isNot(tok::eof))
+        LexUnexpandedToken(Tok);
     }
 
     int Value = 0;
@@ -1441,9 +1445,10 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
       Value = HasFeature(*this, FeatureII);
     }
 
+    if (!IsValid)
+      return;
     OS << Value;
-    if (IsValid)
-      Tok.setKind(tok::numeric_constant);
+    Tok.setKind(tok::numeric_constant);
   } else if (II == Ident__has_include ||
              II == Ident__has_include_next) {
     // The argument to these two builtins should be a parenthesized
@@ -1507,9 +1512,10 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
                               WarningName.substr(2), Diags);
     } while (false);
 
+    if (!IsValid)
+      return;
     OS << (int)Value;
-    if (IsValid)
-      Tok.setKind(tok::numeric_constant);
+    Tok.setKind(tok::numeric_constant);
   } else if (II == Ident__building_module) {
     // The argument to this builtin should be an identifier. The
     // builtin evaluates to 1 when that identifier names the module we are
index 5a2c300e6ee182e325b099b2c170564cbbf76df6..fbde6a65476ed9b2fbd222bf08dabcfb6bb47299 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=i686-apple-darwin9
+// RUN: %clang_cc1 %s -triple=i686-apple-darwin9 -verify -DVERIFY
 // RUN: %clang_cc1 %s -E -triple=i686-apple-darwin9
 #ifndef __has_feature
 #error Should have __has_feature
 #if !HAS_BUILTIN(MY_ALIAS_BUILTIN) || !HAS_FEATURE(MY_ALIAS_FEATURE)
 #error Expansion should have occurred
 #endif
+
+#ifdef VERIFY
+// expected-error@+2 {{builtin feature check macro requires a parenthesized identifier}}
+// expected-error@+1 {{expected value in expression}}
+#if __has_feature('x')
+#endif
+#endif