llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Serosh (Serosh-commits) <details> <summary>Changes</summary> this fixes an assertion failure where the interpreter would crash on invalid initializer lists The problem was that we kept processing expressions even after they were flagged with errors. this led to bad state and the eventual crash so i added checks for `containsErrors()` in compiler.cpp and other entry points so we bail out early instead of asserting. fixes #<!-- -->175432 --- Full diff: https://github.com/llvm/llvm-project/pull/180261.diff 2 Files Affected: - (modified) clang/lib/AST/ByteCode/Compiler.cpp (+21-2) - (added) clang/test/AST/ByteCode/gh175432.cpp (+4) ``````````diff diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index a0138c402e143..a5a9f1e2e440d 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -211,6 +211,9 @@ template <class Emitter> class LocOverrideScope final { template <class Emitter> bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) { + if (CE->containsErrors()) + return false; + const Expr *SubExpr = CE->getSubExpr(); if (DiscardResult) @@ -477,8 +480,6 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) { return this->delegate(SubExpr); case CK_BitCast: { - if (CE->containsErrors()) - return false; QualType CETy = CE->getType(); // Reject bitcasts to atomic types. if (CETy->isAtomicType()) { @@ -1836,6 +1837,9 @@ bool Compiler<Emitter>::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) { template <class Emitter> bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits, const Expr *ArrayFiller, const Expr *E) { + if (E->containsErrors()) + return false; + InitLinkScope<Emitter> ILS(this, InitLink::InitList()); QualType QT = E->getType(); @@ -4264,12 +4268,18 @@ bool Compiler<Emitter>::VisitStmtExpr(const StmtExpr *E) { } template <class Emitter> bool Compiler<Emitter>::discard(const Expr *E) { + if (E->containsErrors()) + return false; + OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true, /*NewInitializing=*/false, /*ToLValue=*/false); return this->Visit(E); } template <class Emitter> bool Compiler<Emitter>::delegate(const Expr *E) { + if (E->containsErrors()) + return false; + // We're basically doing: // OptionScope<Emitter> Scope(this, DicardResult, Initializing, ToLValue); // but that's unnecessary of course. @@ -4302,6 +4312,9 @@ static const Expr *stripDerivedToBaseCasts(const Expr *E) { } template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) { + if (E->containsErrors()) + return false; + if (E->getType().isNull()) return false; @@ -4330,6 +4343,9 @@ template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) { template <class Emitter> bool Compiler<Emitter>::visitInitializer(const Expr *E) { + if (E->containsErrors()) + return false; + assert(!canClassify(E->getType())); OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false, @@ -4338,6 +4354,9 @@ bool Compiler<Emitter>::visitInitializer(const Expr *E) { } template <class Emitter> bool Compiler<Emitter>::visitAsLValue(const Expr *E) { + if (E->containsErrors()) + return false; + OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/false, /*NewInitializing=*/false, /*ToLValue=*/true); return this->Visit(E); diff --git a/clang/test/AST/ByteCode/gh175432.cpp b/clang/test/AST/ByteCode/gh175432.cpp new file mode 100644 index 0000000000000..9433a83c76f56 --- /dev/null +++ b/clang/test/AST/ByteCode/gh175432.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s + +constexpr const int *foo[][2] = { {nullptr, int}, }; // expected-error {{expected expression}} +static_assert(foo[0][0] == nullptr, ""); `````````` </details> https://github.com/llvm/llvm-project/pull/180261 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
