forked from OSchip/llvm-project
fix some problems handling stmtexprs with labels (PR2374), and
improve 'expression unused' diagnostics for stmtexprs. llvm-svn: 54098
This commit is contained in:
parent
06afbebbdd
commit
944d306371
|
@ -347,10 +347,18 @@ bool Expr::hasLocalSideEffect() const {
|
|||
return true;
|
||||
case ObjCMessageExprClass:
|
||||
return true;
|
||||
case StmtExprClass:
|
||||
// TODO: check the inside of the statement expression
|
||||
return true;
|
||||
|
||||
case StmtExprClass: {
|
||||
// Statement exprs don't logically have side effects themselves, but are
|
||||
// sometimes used in macros in ways that give them a type that is unused.
|
||||
// For example ({ blah; foo(); }) will end up with a type if foo has a type.
|
||||
// however, if the result of the stmt expr is dead, we don't want to emit a
|
||||
// warning.
|
||||
const CompoundStmt *CS = cast<StmtExpr>(this)->getSubStmt();
|
||||
if (!CS->body_empty())
|
||||
if (const Expr *E = dyn_cast<Expr>(CS->body_back()))
|
||||
return E->hasLocalSideEffect();
|
||||
return false;
|
||||
}
|
||||
case CastExprClass:
|
||||
// If this is a cast to void, check the operand. Otherwise, the result of
|
||||
// the cast is unused.
|
||||
|
|
|
@ -2334,9 +2334,15 @@ Sema::ExprResult Sema::ActOnStmtExpr(SourceLocation LPLoc, StmtTy *substmt,
|
|||
// as the type of the stmtexpr.
|
||||
QualType Ty = Context.VoidTy;
|
||||
|
||||
if (!Compound->body_empty())
|
||||
if (Expr *LastExpr = dyn_cast<Expr>(Compound->body_back()))
|
||||
if (!Compound->body_empty()) {
|
||||
Stmt *LastStmt = Compound->body_back();
|
||||
// If LastStmt is a label, skip down through into the body.
|
||||
while (LabelStmt *Label = dyn_cast<LabelStmt>(LastStmt))
|
||||
LastStmt = Label->getSubStmt();
|
||||
|
||||
if (Expr *LastExpr = dyn_cast<Expr>(LastStmt))
|
||||
Ty = LastExpr->getType();
|
||||
}
|
||||
|
||||
return new StmtExpr(Compound, Ty, LPLoc, RPLoc);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: clang %s -fsyntax-only
|
||||
// RUN: clang %s -fsyntax-only -verify
|
||||
|
||||
typedef unsigned __uint32_t;
|
||||
|
||||
|
@ -10,3 +10,13 @@ __extension__ ({ register __uint32_t __X = (x); \
|
|||
int test(int _x) {
|
||||
return (__byte_swap_int_var(_x));
|
||||
}
|
||||
|
||||
// PR2374
|
||||
int test2() { return ({L:5;}); }
|
||||
int test3() { return ({ {5;} }); } // expected-error {{incompatible type returning 'void', expected 'int'}}\
|
||||
// expected-warning {{expression result unused}}
|
||||
int test4() { return ({ ({5;}); }); }
|
||||
int test5() { return ({L1: L2: L3: 5;}); }
|
||||
int test6() { return ({5;}); }
|
||||
void test7() { ({5;}); } // expected-warning {{expression result unused}}
|
||||
|
||||
|
|
Loading…
Reference in New Issue