aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-11-19 20:54:25 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-11-19 20:54:25 +0000
commita25b6a4b43e8b9611f7506e5fe1b448833b10a46 (patch)
tree1c8c6e68f978b9b156704e77c31beb8bf573b845 /lib
parentb95cfe4bb01f18a112bcb7eea3b82bc8d6dfe20b (diff)
Don't warn for empty 'if' body if there is a macro that expands to nothing, e.g:
if (condition) CALL(0); // empty macro but don't warn for empty body. Fixes rdar://8436021. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119838 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/Stmt.cpp6
-rw-r--r--lib/Lex/PPMacroExpansion.cpp1
-rw-r--r--lib/Parse/ParseStmt.cpp16
-rw-r--r--lib/Sema/SemaStmt.cpp16
-rw-r--r--lib/Sema/TreeTransform.h8
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp1
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp1
7 files changed, 36 insertions, 13 deletions
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index acd77beaca..85e640701b 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -470,8 +470,10 @@ CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
}
IfStmt::IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond,
- Stmt *then, SourceLocation EL, Stmt *elsev)
- : Stmt(IfStmtClass), IfLoc(IL), ElseLoc(EL)
+ Stmt *then, SourceLocation EL, Stmt *elsev,
+ bool macroExpandedInThenStmt)
+ : Stmt(IfStmtClass), IfLoc(IL), ElseLoc(EL),
+ MacroExpandedInThenStmt(macroExpandedInThenStmt)
{
setConditionVariable(C, var);
SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 2428f9af45..6d2c387d52 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -176,6 +176,7 @@ bool Preprocessor::isNextPPTokenLParen() {
/// expanded as a macro, handle it and return the next token as 'Identifier'.
bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
MacroInfo *MI) {
+ MacroExpansionFlag = true;
if (Callbacks) Callbacks->MacroExpands(Identifier, MI);
// If this is a macro expansion in the "#if !defined(x)" line for the file,
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 12444e87bb..e3c15680c2 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -538,7 +538,8 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
bool Parser::ParseParenExprOrCondition(ExprResult &ExprResult,
Decl *&DeclResult,
SourceLocation Loc,
- bool ConvertToBoolean) {
+ bool ConvertToBoolean,
+ bool *MacroExpandedAfterRParen) {
bool ParseError = false;
SourceLocation LParenLoc = ConsumeParen();
@@ -567,7 +568,14 @@ bool Parser::ParseParenExprOrCondition(ExprResult &ExprResult,
}
// Otherwise the condition is valid or the rparen is present.
+
+ // Catch a macro expansion after ')'. This is used to know that there is a
+ // macro for 'if' body and not warn for empty body if the macro is empty.
+ PPMacroExpansionTrap MacroExpansionTrap(PP);
MatchRHSPunctuation(tok::r_paren, LParenLoc);
+ if (MacroExpandedAfterRParen)
+ *MacroExpandedAfterRParen = MacroExpansionTrap.hasMacroExpansionOccured();
+
return false;
}
@@ -610,7 +618,9 @@ StmtResult Parser::ParseIfStatement(AttributeList *Attr) {
// Parse the condition.
ExprResult CondExp;
Decl *CondVar = 0;
- if (ParseParenExprOrCondition(CondExp, CondVar, IfLoc, true))
+ bool MacroExpandedInThenStmt;
+ if (ParseParenExprOrCondition(CondExp, CondVar, IfLoc, true,
+ &MacroExpandedInThenStmt))
return StmtError();
FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp.get()));
@@ -694,7 +704,7 @@ StmtResult Parser::ParseIfStatement(AttributeList *Attr) {
ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
return Actions.ActOnIfStmt(IfLoc, FullCondExp, CondVar, ThenStmt.get(),
- ElseLoc, ElseStmt.get());
+ MacroExpandedInThenStmt, ElseLoc, ElseStmt.get());
}
/// ParseSwitchStatement
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index a4f1d34aec..c6194edac3 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -282,8 +282,8 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
StmtResult
Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,
- Stmt *thenStmt, SourceLocation ElseLoc,
- Stmt *elseStmt) {
+ Stmt *thenStmt, bool MacroExpandedInThenStmt,
+ SourceLocation ElseLoc, Stmt *elseStmt) {
ExprResult CondResult(CondVal.release());
VarDecl *ConditionVar = 0;
@@ -304,17 +304,23 @@ Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,
// if (condition);
// do_stuff();
//
- // NOTE: Do not emit this warning if the body is expanded from a macro.
if (!elseStmt) {
if (NullStmt* stmt = dyn_cast<NullStmt>(thenStmt))
- if (!stmt->getLocStart().isMacroID())
+ // But do not warn if the body is a macro that expands to nothing, e.g:
+ //
+ // #define CALL(x)
+ // if (condition)
+ // CALL(0);
+ //
+ if (!MacroExpandedInThenStmt)
Diag(stmt->getSemiLoc(), diag::warn_empty_if_body);
}
DiagnoseUnusedExprResult(elseStmt);
return Owned(new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
- thenStmt, ElseLoc, elseStmt));
+ thenStmt, ElseLoc, elseStmt,
+ MacroExpandedInThenStmt));
}
/// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 807346c4c5..3ae4e5c5f4 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -772,9 +772,11 @@ public:
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
StmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
- VarDecl *CondVar, Stmt *Then,
+ VarDecl *CondVar, Stmt *Then,
+ bool MacroExpandedInThenStmt,
SourceLocation ElseLoc, Stmt *Else) {
- return getSema().ActOnIfStmt(IfLoc, Cond, CondVar, Then, ElseLoc, Else);
+ return getSema().ActOnIfStmt(IfLoc, Cond, CondVar, Then,
+ MacroExpandedInThenStmt, ElseLoc, Else);
}
/// \brief Start building a new switch statement.
@@ -3692,7 +3694,7 @@ TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
return SemaRef.Owned(S);
return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, ConditionVar,
- Then.get(),
+ Then.get(), S->hasMacroExpandedInThenStmt(),
S->getElseLoc(), Else.get());
}
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 6d578f616e..a7b42cd3fc 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -256,6 +256,7 @@ void ASTStmtReader::VisitIfStmt(IfStmt *S) {
S->setElse(Reader.ReadSubStmt());
S->setIfLoc(ReadSourceLocation(Record, Idx));
S->setElseLoc(ReadSourceLocation(Record, Idx));
+ S->MacroExpandedInThenStmt = Record[Idx++];
}
void ASTStmtReader::VisitSwitchStmt(SwitchStmt *S) {
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 495c3d05ff..a59b772da4 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -228,6 +228,7 @@ void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
Writer.AddStmt(S->getElse());
Writer.AddSourceLocation(S->getIfLoc(), Record);
Writer.AddSourceLocation(S->getElseLoc(), Record);
+ Record.push_back(S->MacroExpandedInThenStmt);
Code = serialization::STMT_IF;
}