Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Assertion `idx < size()' failed in HandleUnionActiveMemberChange #44849

Open Quuxplusone opened 4 years ago

Quuxplusone commented 4 years ago
Bugzilla Link PR45879
Status CONFIRMED
Importance P enhancement
Reported by Peter Collingbourne (peter@pcc.me.uk)
Reported on 2020-05-11 18:11:01 -0700
Last modified on 2021-04-30 10:37:04 -0700
Version unspecified
Hardware PC All
CC arthur.j.odwyer@gmail.com, llvm-bugs@lists.llvm.org, neeilans@live.com, raul@tambre.ee, richard-llvm@metafoo.co.uk, sepavloff@gmail.com, srhines@google.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
$ cat test-formatted.ii
struct a {
  char b = 0;
};

struct s {
  a f;
};

constexpr void m() {
  a l;
  l = s{}.f;
}

void p() { return m(); }
$ clang++ -c -o test.o test-formatted.ii -std=gnu++2a
clang++: ../llvm/include/llvm/ADT/SmallVector.h:180:
llvm::SmallVectorTemplateCommon::const_reference
llvm::SmallVectorTemplateCommon<clang::APValue::LValuePathEntry,
void>::operator[](llvm::SmallVectorTemplateCommon::size_type) const [T =
clang::APValue::LValuePathEntry]: Assertion `idx < size()' failed.
Quuxplusone commented 4 years ago

Unable to reproduce with the latest trunk.

Quuxplusone commented 4 years ago

Are you sure that you are building with assertions enabled? (e.g. cmake -DLLVM_ENABLE_ASSERTIONS=1)

Quuxplusone commented 4 years ago
Seems you're right. Apologies.
Been building recently as RelWithDebInfo for faster testing and hadn't realized
assertions weren't enabled.
Quuxplusone commented 4 years ago
The crash happens because LHS.Designator.Entries is empty, thus PathLength is
0. PathLength is then decremented resulting in an underflow to 4294967295,
which is used to index LHS.Designator.Entries in the assert in the MemberExpr
code path in HandleUnionActiveMemberChange.

It's trivial to fix this to not crash, but no idea what a proper fix would be.

Callstack:
#11 0x00000000088ec8ca HandleUnionActiveMemberChange((anonymous
namespace)::EvalInfo&, clang::Expr const*, (anonymous namespace)::LValue
const&) /opt/llvm/clang/lib/AST/ExprConstant.cpp:5453:7
#12 0x00000000088e37cc HandleFunctionCall(clang::SourceLocation,
clang::FunctionDecl const*, (anonymous namespace)::LValue const*,
llvm::ArrayRef<clang::Expr const*>, clang::Stmt const*, (anonymous
namespace)::EvalInfo&, clang::APValue&, (anonymous namespace)::LValue const*)
/opt/llvm/clang/lib/AST/ExprConstant.cpp:5598:9
#13 0x000000000896645a (anonymous namespace)::ExprEvaluatorBase<(anonymous
namespace)::LValueExprEvaluator>::handleCallExpr(clang::CallExpr const*,
clang::APValue&, (anonymous namespace)::LValue const*)
/opt/llvm/clang/lib/AST/ExprConstant.cpp:7127:9
#14 0x00000000088ea304 (anonymous namespace)::ExprEvaluatorBase<(anonymous
namespace)::LValueExprEvaluator>::VisitCallExpr(clang::CallExpr const*)
/opt/llvm/clang/lib/AST/ExprConstant.cpp:6973:9
#15 0x00000000088ea3e3 clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous
namespace)::LValueExprEvaluator,
bool>::VisitCXXOperatorCallExpr(clang::CXXOperatorCallExpr const*)
/opt/llvm/build/tools/clang/include/clang/AST/StmtNodes.inc:829:1
#16 0x00000000088e6bb8 clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous
namespace)::LValueExprEvaluator, bool>::Visit(clang::Stmt const*)
/opt/llvm/build/tools/clang/include/clang/AST/StmtNodes.inc:829:1
#17 0x00000000088eae94 (anonymous namespace)::ExprEvaluatorBase<(anonymous
namespace)::LValueExprEvaluator>::VisitExprWithCleanups(clang::ExprWithCleanups
const*) /opt/llvm/clang/lib/AST/ExprConstant.cpp:6838:27
#18 0x00000000088e6f01 clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous
namespace)::LValueExprEvaluator, bool>::Visit(clang::Stmt const*)
/opt/llvm/build/tools/clang/include/clang/AST/StmtNodes.inc:1043:1
#19 0x00000000088dd3bf EvaluateLValue(clang::Expr const*, (anonymous
namespace)::LValue&, (anonymous namespace)::EvalInfo&, bool)
/opt/llvm/clang/lib/AST/ExprConstant.cpp:7549:3
#20 0x00000000088de735 Evaluate(clang::APValue&, (anonymous
namespace)::EvalInfo&, clang::Expr const*)
/opt/llvm/clang/lib/AST/ExprConstant.cpp:13652:9
#21 0x00000000088ffd6a EvaluateIgnoredValue((anonymous namespace)::EvalInfo&,
clang::Expr const*) /opt/llvm/clang/lib/AST/ExprConstant.cpp:1872:7
#22 0x000000000890c519 EvaluateStmt((anonymous namespace)::StmtResult&,
(anonymous namespace)::EvalInfo&, clang::Stmt const*, clang::SwitchCase const*)
/opt/llvm/clang/lib/AST/ExprConstant.cpp:4673:42
#23 0x000000000890c899 EvaluateStmt((anonymous namespace)::StmtResult&,
(anonymous namespace)::EvalInfo&, clang::Stmt const*, clang::SwitchCase const*)
/opt/llvm/clang/lib/AST/ExprConstant.cpp:4713:22
#24 0x00000000088e3952 HandleFunctionCall(clang::SourceLocation,
clang::FunctionDecl const*, (anonymous namespace)::LValue const*,
llvm::ArrayRef<clang::Expr const*>, clang::Stmt const*, (anonymous
namespace)::EvalInfo&, clang::APValue&, (anonymous namespace)::LValue const*)
/opt/llvm/clang/lib/AST/ExprConstant.cpp:5619:18
#25 0x000000000899138a (anonymous namespace)::ExprEvaluatorBase<(anonymous
namespace)::VoidExprEvaluator>::handleCallExpr(clang::CallExpr const*,
clang::APValue&, (anonymous namespace)::LValue const*)
/opt/llvm/clang/lib/AST/ExprConstant.cpp:7127:9
#26 0x00000000089905b4 (anonymous namespace)::ExprEvaluatorBase<(anonymous
namespace)::VoidExprEvaluator>::VisitCallExpr(clang::CallExpr const*)
/opt/llvm/clang/lib/AST/ExprConstant.cpp:6973:9
#27 0x000000000898db94 (anonymous
namespace)::VoidExprEvaluator::VisitCallExpr(clang::CallExpr const*)
/opt/llvm/clang/lib/AST/ExprConstant.cpp:13557:5
#28 0x000000000898a6a1 clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous
namespace)::VoidExprEvaluator, bool>::Visit(clang::Stmt const*)
/opt/llvm/build/tools/clang/include/clang/AST/StmtNodes.inc:813:1
#29 0x000000000897fcb0 EvaluateVoid(clang::Expr const*, (anonymous
namespace)::EvalInfo&) /opt/llvm/clang/lib/AST/ExprConstant.cpp:13639:3
#30 0x00000000088dedc9 Evaluate(clang::APValue&, (anonymous
namespace)::EvalInfo&, clang::Expr const*)
/opt/llvm/clang/lib/AST/ExprConstant.cpp:13701:9
#31 0x00000000088e03bc EvaluateAsRValue((anonymous namespace)::EvalInfo&,
clang::Expr const*, clang::APValue&)
/opt/llvm/clang/lib/AST/ExprConstant.cpp:13767:9
#32 0x00000000088dc751 EvaluateAsRValue(clang::Expr const*,
clang::Expr::EvalResult&, clang::ASTContext const&, (anonymous
namespace)::EvalInfo&) /opt/llvm/clang/lib/AST/ExprConstant.cpp:13824:3
#33 0x00000000088dc519 clang::Expr::EvaluateAsRValue(clang::Expr::EvalResult&,
clang::ASTContext const&, bool) const
/opt/llvm/clang/lib/AST/ExprConstant.cpp:13871:1
#34 0x00000000088dfe90 clang::Expr::isEvaluatable(clang::ASTContext const&,
clang::Expr::SideEffectsKind) const
/opt/llvm/clang/lib/AST/ExprConstant.cpp:14058:10
#35 0x0000000005fb0ef4
clang::CodeGen::CodeGenFunction::EmitReturnStmt(clang::ReturnStmt const&)
/opt/llvm/clang/lib/CodeGen/CGStmt.cpp:1152:7
#36 0x0000000005fae30d clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt
const*, llvm::ArrayRef<clang::Attr const*>)
/opt/llvm/clang/lib/CodeGen/CGStmt.cpp:147:75
#37 0x0000000005fb654b
clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt
const&, bool, clang::CodeGen::AggValueSlot)
/opt/llvm/clang/lib/CodeGen/CGStmt.cpp:417:3
#38 0x0000000005e24120
clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::Stmt const*)
/opt/llvm/clang/lib/CodeGen/CodeGenFunction.cpp:1109:5
#39 0x0000000005e24bad
clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl,
llvm::Function*, clang::CodeGen::CGFunctionInfo const&)
/opt/llvm/clang/lib/CodeGen/CodeGenFunction.cpp:1275:3
#40 0x0000000005cecafa
clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl,
llvm::GlobalValue*) /opt/llvm/clang/lib/CodeGen/CodeGenModule.cpp:4520:3
#41 0x0000000005ce4406
clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl,
llvm::GlobalValue*) /opt/llvm/clang/lib/CodeGen/CodeGenModule.cpp:2894:12
#42 0x0000000005ce861e
clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl)
/opt/llvm/clang/lib/CodeGen/CodeGenModule.cpp:2647:5
#43 0x0000000005cf05e8
clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*)
/opt/llvm/clang/lib/CodeGen/CodeGenModule.cpp:5329:38
Quuxplusone commented 3 years ago
Here's another repro.

cat >test.cpp <<EOF
struct Base { int m; };
struct Derived : Base {};
constexpr int k = ((Base{} = Derived{}), 0);
EOF
clang++ -std=c++20 -w -c test.cpp

This causes an assertion failure, so it reproduces only in Debug mode.
Reproing REQUIRES c++20; it works as expected in c++14 and c++17 modes, so it's
something new in c++20 that's causing the problem.

It's weird that the stacktrace points to `HandleUnionActiveMemberChange`, when
this test case doesn't involve any unions. Maybe that's related to the bug?

This crash started happening on buildbots after I implemented P1032 constexpr
tuple for libc++; see the post-commit comments on
https://reviews.llvm.org/D96385 .
Quuxplusone commented 3 years ago
This might be stating the obvious ;) but indeed the assert-fail starts
happening with this specific commit:

commit 31c69a3d6363463c08b86914c0c8cfc5c929c37e
Author: Richard Smith <richard-llvm@metafoo.co.uk>
Date:   Tue May 21 23:15:20 2019 +0000

    [c++20] P1330R0: permit simple-assignments that change the active member
    of a union within constant expression evaluation.

    llvm-svn: 361329
Quuxplusone commented 3 years ago

Patch that fixes this bug is here: https://reviews.llvm.org/D101429