Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -9690,6 +9690,7 @@ class ConditionResult { Decl *ConditionVar; FullExprArg Condition; + SourceLocation RParenLoc; bool Invalid; bool HasKnownValue; bool KnownValue; @@ -9713,6 +9714,11 @@ return std::make_pair(cast_or_null(ConditionVar), Condition.get()); } + + void setRParLoc(SourceLocation Loc) { + RParenLoc = Loc; + } + llvm::Optional getKnownValue() const { if (!HasKnownValue) return None; Index: lib/Parse/ParseStmt.cpp =================================================================== --- lib/Parse/ParseStmt.cpp +++ lib/Parse/ParseStmt.cpp @@ -1101,6 +1101,7 @@ // Otherwise the condition is valid or the rparen is present. T.consumeClose(); + Cond.setRParLoc(T.getCloseLocation()); // Check for extraneous ')'s to catch things like "if (foo())) {". We know // that all callers are looking for a statement after the condition, so ")" Index: lib/Sema/SemaChecking.cpp =================================================================== --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -11815,7 +11815,7 @@ // Get line numbers of statement and body. bool StmtLineInvalid; - unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc, + unsigned StmtLine = SourceMgr.getSpellingLineNumber(StmtLoc, &StmtLineInvalid); if (StmtLineInvalid) return false; Index: lib/Sema/SemaStmt.cpp =================================================================== --- lib/Sema/SemaStmt.cpp +++ lib/Sema/SemaStmt.cpp @@ -530,8 +530,7 @@ if (elseStmt) DiagnoseEmptyStmtBody(ElseLoc, elseStmt, diag::warn_empty_else_body); else - DiagnoseEmptyStmtBody(CondExpr->getLocEnd(), thenStmt, - diag::warn_empty_if_body); + DiagnoseEmptyStmtBody(Cond.RParenLoc, thenStmt, diag::warn_empty_if_body); return BuildIfStmt(IfLoc, IsConstexpr, InitStmt, Cond, thenStmt, ElseLoc, elseStmt); Index: test/SemaCXX/warn-empty-body.cpp =================================================================== --- test/SemaCXX/warn-empty-body.cpp +++ test/SemaCXX/warn-empty-body.cpp @@ -301,3 +301,14 @@ if (x) IDENTITY(); // no-warning } +#define SOME_IF(A) if (A) +#define IF_ELSE(A) if (A); else + + +void test_macros() { + SOME_IF(0); + IF_ELSE(0); + + IDENTITY(if (0);) // expected-warning{{if statement has empty body}} expected-note{{separate line}} + IDENTITY(if (0); else;) // expected-warning{{else clause has empty body}} expected-note{{separate line}}} +}