diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Stmt.cpp | 6 | ||||
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 1 | ||||
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 16 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 16 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 8 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 1 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 1 |
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; } |