[CGExprAgg] Fix infinite loop in `findPeephole`

Simplify the function using IgnoreParenNoopCasts.

Fix PR45476

Differential Revision: https://reviews.llvm.org/D78098
This commit is contained in:
Ehud Katz 2020-04-16 13:26:23 +03:00
parent 921009e667
commit 03a9526fe5
2 changed files with 27 additions and 11 deletions

View File

@ -677,17 +677,13 @@ AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
/// Attempt to look through various unimportant expressions to find a
/// cast of the given kind.
static Expr *findPeephole(Expr *op, CastKind kind) {
while (true) {
op = op->IgnoreParens();
if (CastExpr *castE = dyn_cast<CastExpr>(op)) {
if (castE->getCastKind() == kind)
return castE->getSubExpr();
if (castE->getCastKind() == CK_NoOp)
continue;
}
return nullptr;
static Expr *findPeephole(Expr *op, CastKind kind, const ASTContext &ctx) {
op = op->IgnoreParenNoopCasts(ctx);
if (auto castE = dyn_cast<CastExpr>(op)) {
if (castE->getCastKind() == kind)
return castE->getSubExpr();
}
return nullptr;
}
void AggExprEmitter::VisitCastExpr(CastExpr *E) {
@ -776,7 +772,8 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
(isToAtomic ? CK_AtomicToNonAtomic : CK_NonAtomicToAtomic);
// These two cases are reverses of each other; try to peephole them.
if (Expr *op = findPeephole(E->getSubExpr(), peepholeTarget)) {
if (Expr *op =
findPeephole(E->getSubExpr(), peepholeTarget, CGF.getContext())) {
assert(CGF.getContext().hasSameUnqualifiedType(op->getType(),
E->getType()) &&
"peephole significantly changed types?");

View File

@ -0,0 +1,19 @@
// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
// PR45476
// This test used to get into an infinite loop,
// which, in turn, caused clang to never finish execution.
struct s3 {
char a, b, c;
};
_Atomic struct s3 a;
extern "C" void foo() {
// CHECK-LABEL: @foo
// CHECK: store atomic i32
a = s3{1, 2, 3};
}