r266495 - Improve diagnostic for the case when a non-defined function-like macro is used
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 15 17:07:11 PDT 2016
Author: rsmith
Date: Fri Apr 15 19:07:09 2016
New Revision: 266495
URL: http://llvm.org/viewvc/llvm-project?rev=266495&view=rev
Log:
Improve diagnostic for the case when a non-defined function-like macro is used
in a preprocessor constant expression.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
cfe/trunk/lib/Lex/PPExpressions.cpp
cfe/trunk/test/Preprocessor/expr_invalid_tok.c
cfe/trunk/test/Preprocessor/has_attribute.c
Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=266495&r1=266494&r2=266495&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Fri Apr 15 19:07:09 2016
@@ -409,6 +409,8 @@ def err_pp_remainder_by_zero : Error<
"remainder by zero in preprocessor expression">;
def err_pp_expr_bad_token_binop : Error<
"token is not a valid binary operator in a preprocessor subexpression">;
+def err_pp_expr_bad_token_lparen : Error<
+ "function-like macro %0 is not defined">;
def err_pp_expr_bad_token_start_expr : Error<
"invalid token at start of a preprocessor expression">;
def err_pp_invalid_poison : Error<"can only poison identifier tokens">;
Modified: cfe/trunk/lib/Lex/PPExpressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPExpressions.cpp?rev=266495&r1=266494&r2=266495&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPExpressions.cpp (original)
+++ cfe/trunk/lib/Lex/PPExpressions.cpp Fri Apr 15 19:07:09 2016
@@ -33,12 +33,18 @@ namespace {
/// conditional and the source range covered by it.
class PPValue {
SourceRange Range;
+ IdentifierInfo *II;
public:
llvm::APSInt Val;
// Default ctor - Construct an 'invalid' PPValue.
PPValue(unsigned BitWidth) : Val(BitWidth) {}
+ // If this value was produced by directly evaluating an identifier, produce
+ // that identifier.
+ IdentifierInfo *getIdentifier() const { return II; }
+ void setIdentifier(IdentifierInfo *II) { this->II = II; }
+
unsigned getBitWidth() const { return Val.getBitWidth(); }
bool isUnsigned() const { return Val.isUnsigned(); }
@@ -209,6 +215,8 @@ static bool EvaluateValue(PPValue &Resul
bool ValueLive, Preprocessor &PP) {
DT.State = DefinedTracker::Unknown;
+ Result.setIdentifier(nullptr);
+
if (PeekTok.is(tok::code_completion)) {
if (PP.getCodeCompletionHandler())
PP.getCodeCompletionHandler()->CodeCompletePreprocessorExpression();
@@ -234,6 +242,7 @@ static bool EvaluateValue(PPValue &Resul
PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
Result.Val = II->getTokenID() == tok::kw_true;
Result.Val.setIsUnsigned(false); // "0" is signed intmax_t 0.
+ Result.setIdentifier(II);
Result.setRange(PeekTok.getLocation());
PP.LexNonComment(PeekTok);
return false;
@@ -392,6 +401,7 @@ static bool EvaluateValue(PPValue &Resul
DT.State = DefinedTracker::Unknown;
}
Result.setRange(Start, PeekTok.getLocation());
+ Result.setIdentifier(nullptr);
PP.LexNonComment(PeekTok); // Eat the ).
return false;
}
@@ -401,6 +411,7 @@ static bool EvaluateValue(PPValue &Resul
PP.LexNonComment(PeekTok);
if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
Result.setBegin(Start);
+ Result.setIdentifier(nullptr);
return false;
}
case tok::minus: {
@@ -408,6 +419,7 @@ static bool EvaluateValue(PPValue &Resul
PP.LexNonComment(PeekTok);
if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
Result.setBegin(Loc);
+ Result.setIdentifier(nullptr);
// C99 6.5.3.3p3: The sign of the result matches the sign of the operand.
Result.Val = -Result.Val;
@@ -428,6 +440,7 @@ static bool EvaluateValue(PPValue &Resul
PP.LexNonComment(PeekTok);
if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
Result.setBegin(Start);
+ Result.setIdentifier(nullptr);
// C99 6.5.3.3p4: The sign of the result matches the sign of the operand.
Result.Val = ~Result.Val;
@@ -443,6 +456,7 @@ static bool EvaluateValue(PPValue &Resul
Result.Val = !Result.Val;
// C99 6.5.3.3p5: The sign of the result is 'int', aka it is signed.
Result.Val.setIsUnsigned(false);
+ Result.setIdentifier(nullptr);
if (DT.State == DefinedTracker::DefinedMacro)
DT.State = DefinedTracker::NotDefinedMacro;
@@ -491,6 +505,15 @@ static unsigned getPrecedence(tok::Token
}
}
+static void diagnoseUnexpectedOperator(Preprocessor &PP, PPValue &LHS,
+ Token &Tok) {
+ if (Tok.is(tok::l_paren) && LHS.getIdentifier())
+ PP.Diag(LHS.getRange().getBegin(), diag::err_pp_expr_bad_token_lparen)
+ << LHS.getIdentifier();
+ else
+ PP.Diag(Tok.getLocation(), diag::err_pp_expr_bad_token_binop)
+ << LHS.getRange();
+}
/// EvaluateDirectiveSubExpr - Evaluate the subexpression whose first token is
/// PeekTok, and whose precedence is PeekPrec. This returns the result in LHS.
@@ -504,8 +527,7 @@ static bool EvaluateDirectiveSubExpr(PPV
unsigned PeekPrec = getPrecedence(PeekTok.getKind());
// If this token isn't valid, report the error.
if (PeekPrec == ~0U) {
- PP.Diag(PeekTok.getLocation(), diag::err_pp_expr_bad_token_binop)
- << LHS.getRange();
+ diagnoseUnexpectedOperator(PP, LHS, PeekTok);
return true;
}
@@ -548,8 +570,7 @@ static bool EvaluateDirectiveSubExpr(PPV
// If this token isn't valid, report the error.
if (PeekPrec == ~0U) {
- PP.Diag(PeekTok.getLocation(), diag::err_pp_expr_bad_token_binop)
- << RHS.getRange();
+ diagnoseUnexpectedOperator(PP, RHS, PeekTok);
return true;
}
@@ -769,6 +790,7 @@ static bool EvaluateDirectiveSubExpr(PPV
// Put the result back into 'LHS' for our next iteration.
LHS.Val = Res;
LHS.setEnd(RHS.getRange().getEnd());
+ RHS.setIdentifier(nullptr);
}
}
Modified: cfe/trunk/test/Preprocessor/expr_invalid_tok.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/expr_invalid_tok.c?rev=266495&r1=266494&r2=266495&view=diff
==============================================================================
--- cfe/trunk/test/Preprocessor/expr_invalid_tok.c (original)
+++ cfe/trunk/test/Preprocessor/expr_invalid_tok.c Fri Apr 15 19:07:09 2016
@@ -1,15 +1,28 @@
-// RUN: not %clang_cc1 -E %s 2>&1 | grep 'invalid token at start of a preprocessor expression'
-// RUN: not %clang_cc1 -E %s 2>&1 | grep 'token is not a valid binary operator in a preprocessor subexpression'
-// RUN: not %clang_cc1 -E %s 2>&1 | grep ':14: error: expected end of line in preprocessor expression'
+// RUN: not %clang_cc1 -E %s 2>&1 | FileCheck %s
// PR2220
+// CHECK: invalid token at start of a preprocessor expression
#if 1 * * 2
#endif
+// CHECK: token is not a valid binary operator in a preprocessor subexpression
#if 4 [ 2
#endif
// PR2284 - The constant-expr production does not including comma.
+// CHECK: [[@LINE+1]]:14: error: expected end of line in preprocessor expression
#if 1 ? 2 : 0, 1
#endif
+
+// CHECK: [[@LINE+1]]:5: error: function-like macro 'FOO' is not defined
+#if FOO(1, 2, 3)
+#endif
+
+// CHECK: [[@LINE+1]]:9: error: function-like macro 'BAR' is not defined
+#if 1 + BAR(1, 2, 3)
+#endif
+
+// CHECK: [[@LINE+1]]:10: error: token is not a valid binary operator
+#if (FOO)(1, 2, 3)
+#endif
Modified: cfe/trunk/test/Preprocessor/has_attribute.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/has_attribute.c?rev=266495&r1=266494&r2=266495&view=diff
==============================================================================
--- cfe/trunk/test/Preprocessor/has_attribute.c (original)
+++ cfe/trunk/test/Preprocessor/has_attribute.c Fri Apr 15 19:07:09 2016
@@ -54,5 +54,5 @@ int has_no_volatile_attribute();
int does_not_have_uuid
#endif
-#if __has_cpp_attribute(selectany) // expected-error {{token is not a valid binary operator in a preprocessor subexpression}}
+#if __has_cpp_attribute(selectany) // expected-error {{function-like macro '__has_cpp_attribute' is not defined}}
#endif
More information about the cfe-commits
mailing list