From: Ehud Katz Date: Thu, 16 Apr 2020 10:26:23 +0000 (+0300) Subject: [CGExprAgg] Fix infinite loop in `findPeephole` X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=03a9526fe5adae909f1d5fd2736703e69fc46e09;p=platform%2Fupstream%2Fllvm.git [CGExprAgg] Fix infinite loop in `findPeephole` Simplify the function using IgnoreParenNoopCasts. Fix PR45476 Differential Revision: https://reviews.llvm.org/D78098 --- diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index fa2d228..90d4f7e 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -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(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(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?"); diff --git a/clang/test/CodeGen/pr45476.cpp b/clang/test/CodeGen/pr45476.cpp new file mode 100644 index 0000000..61f3f36 --- /dev/null +++ b/clang/test/CodeGen/pr45476.cpp @@ -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}; +} +