From: David Majnemer Date: Mon, 15 Dec 2014 09:03:58 +0000 (+0000) Subject: Preprocessor: Recover instead of mutating a token in ExpandBuiltinMacro X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a478cbc1f8716ccf953df8509e0d0bb2593765be;p=clang Preprocessor: Recover instead of mutating a token in ExpandBuiltinMacro 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 --- diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index d9a7f39913..cd05d06633 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -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 diff --git a/test/Preprocessor/feature_tests.c b/test/Preprocessor/feature_tests.c index 5a2c300e6e..fbde6a6547 100644 --- a/test/Preprocessor/feature_tests.c +++ b/test/Preprocessor/feature_tests.c @@ -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 @@ -53,3 +53,10 @@ #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