Open Quuxplusone opened 4 years ago
Attached c6.cpp
(2392 bytes, text/plain): Source
Attached c6-62bb79.cpp
(2422 bytes, text/plain): Preprocessed source file.
Attached c6-62bb79.sh
(1966 bytes, text/plain): Clang generated shell script
I believe this is the same bug I ran into:
Reproducer:
template <class T> struct A {
static T x;
static T&& y;
};
template <class T> T A<T>::x = 59;
template <class T> T&& A<T>::y = x;
int z = A<wchar_t>::y;
Diagnostic (note, file names/line numbers removed):
error: rvalue reference to type 'wchar_t' cannot bind to lvalue of type
'wchar_t'
template <class T> T&& A<T>::y = x;
note: in instantiation of static data member 'A<wchar_t>::y' requested here
int z = A<wchar_t>::y;
Assert log:
clang: /iusers/ekeane1/workspaces/llvm-
project/clang/lib/AST/ExprConstant.cpp:3079: bool
evaluateVarDeclInit({anonymous}::EvalInfo&, const clang::Expr*, const
clang::VarDecl*, {anonymous}::CallStackFrame*, clang::APValue*&, const
{anonymous}::LValue*): Assertion `!VD-
>mightBeUsableInConstantExpressions(Info.Ctx)' failed.
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash
backtrace, preprocessed source, and associated run script.
Stack dump:
0. Program arguments: ./bin/clang -cc1 cls_static03.cpp
1. cls_static03.cpp:14:22: current parser token ';'
#0 0x0000000004ba981c llvm::sys::PrintStackTrace(llvm::raw_ostream&) /iusers/ekeane1/workspaces/llvm-project/llvm/lib/Support/Unix/Signals.inc:564:22
#1 0x0000000004ba98af PrintStackTraceSignalHandler(void*) /iusers/ekeane1/workspaces/llvm-project/llvm/lib/Support/Unix/Signals.inc:625:1
#2 0x0000000004ba7941 llvm::sys::RunSignalHandlers() /iusers/ekeane1/workspaces/llvm-project/llvm/lib/Support/Signals.cpp:68:20
#3 0x0000000004ba925f SignalHandler(int) /iusers/ekeane1/workspaces/llvm-project/llvm/lib/Support/Unix/Signals.inc:406:1
#4 0x00007fbad340c5e0 __restore_rt (/lib64/libpthread.so.0+0xf5e0)
#5 0x00007fbad1f851f7 raise (/lib64/libc.so.6+0x351f7)
#6 0x00007fbad1f868e8 abort (/lib64/libc.so.6+0x368e8)
#7 0x00007fbad1f7e266 __assert_fail_base (/lib64/libc.so.6+0x2e266)
#8 0x00007fbad1f7e312 (/lib64/libc.so.6+0x2e312)
#9 0x0000000008c2eca2 evaluateVarDeclInit((anonymous namespace)::EvalInfo&, clang::Expr const*, clang::VarDecl const*, (anonymous namespace)::CallStackFrame*, clang::APValue*&, (anonymous namespace)::LValue const*) /iusers/ekeane1/workspaces/llvm-project/clang/lib/AST/ExprConstant.cpp:3080:51
#10 0x0000000008c3f922 (anonymous
namespace)::LValueExprEvaluator::VisitVarDecl(clang::Expr const*,
clang::VarDecl const*) /iusers/ekeane1/workspaces/llvm-
project/clang/lib/AST/ExprConstant.cpp:7830:7
#11 0x0000000008c3f42e (anonymous
namespace)::LValueExprEvaluator::VisitDeclRefExpr(clang::DeclRefExpr const*)
/iusers/ekeane1/workspaces/llvm-project/clang/lib/AST/ExprConstant.cpp:7762:30
#12 0x0000000008c68a6a clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous
namespace)::LValueExprEvaluator, bool>::Visit(clang::Stmt const*)
/iusers/ekeane1/workspaces/llvm-project/build/tools/clang/include/clang/AST/StmtNodes.inc:979:1
#13 0x0000000008c3f38a EvaluateLValue(clang::Expr const*, (anonymous
namespace)::LValue&, (anonymous namespace)::EvalInfo&, bool)
/iusers/ekeane1/workspaces/llvm-project/clang/lib/AST/ExprConstant.cpp:7755:66
#14 0x0000000008c5a8bf Evaluate(clang::APValue&, (anonymous
namespace)::EvalInfo&, clang::Expr const*) /iusers/ekeane1/workspaces/llvm-
project/clang/lib/AST/ExprConstant.cpp:13950:9
#15 0x0000000008c5b447 EvaluateAsRValue((anonymous namespace)::EvalInfo&,
clang::Expr const*, clang::APValue&) /iusers/ekeane1/workspaces/llvm-
project/clang/lib/AST/ExprConstant.cpp:14065:9
#16 0x0000000008c5b812 EvaluateAsRValue(clang::Expr const*,
clang::Expr::EvalResult&, clang::ASTContext const&, (anonymous
namespace)::EvalInfo&) /iusers/ekeane1/workspaces/llvm-
project/clang/lib/AST/ExprConstant.cpp:14122:46
#17 0x0000000008c5ba37 clang::Expr::EvaluateAsRValue(clang::Expr::EvalResult&,
clang::ASTContext const&, bool) const /iusers/ekeane1/workspaces/llvm-
project/clang/lib/AST/ExprConstant.cpp:14168:28
#18 0x00000000079ba287 GetExprRange(clang::ASTContext&, clang::Expr const*,
unsigned int, bool) /iusers/ekeane1/workspaces/llvm-
project/clang/lib/Sema/SemaChecking.cpp:10269:3
#19 0x00000000079baedd GetExprRange(clang::ASTContext&, clang::Expr const*,
bool) /iusers/ekeane1/workspaces/llvm-
project/clang/lib/Sema/SemaChecking.cpp:10491:1
#20 0x00000000079c143b CheckImplicitConversion(clang::Sema&, clang::Expr*,
clang::QualType, clang::SourceLocation, bool*, bool)
/iusers/ekeane1/workspaces/llvm-project/clang/lib/Sema/SemaChecking.cpp:11878:76
#21 0x00000000079c25a6 AnalyzeImplicitConversions(clang::Sema&, (anonymous
namespace)::AnalyzeImplicitConversionsWorkItem,
llvm::SmallVectorImpl<(anonymous
namespace)::AnalyzeImplicitConversionsWorkItem>&)
/iusers/ekeane1/workspaces/llvm-project/clang/lib/Sema/SemaChecking.cpp:12123:57
#22 0x00000000079c2d2b AnalyzeImplicitConversions(clang::Sema&, clang::Expr*,
clang::SourceLocation, bool) /iusers/ekeane1/workspaces/llvm-
project/clang/lib/Sema/SemaChecking.cpp:12208:3
#23 0x00000000079c3fc6 clang::Sema::CheckImplicitConversions(clang::Expr*,
clang::SourceLocation) /iusers/ekeane1/workspaces/llvm-
project/clang/lib/Sema/SemaChecking.cpp:12488:29
#24 0x00000000079c6dd1 clang::Sema::CheckCompletedExpr(clang::Expr*,
clang::SourceLocation, bool) /iusers/ekeane1/workspaces/llvm-
project/clang/lib/Sema/SemaChecking.cpp:13389:35
#25 0x0000000007f06327 clang::Sema::ActOnFinishFullExpr(clang::Expr*,
clang::SourceLocation, bool, bool) /iusers/ekeane1/workspaces/llvm-
project/clang/lib/Sema/SemaExprCXX.cpp:8362:19
#26 0x0000000007ae1f34 clang::Sema::AddInitializerToDecl(clang::Decl*,
clang::Expr*, bool) /iusers/ekeane1/workspaces/llvm-
project/clang/lib/Sema/SemaDecl.cpp:12147:73
#27 0x000000000781e3ae
clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes(clang::Declarator&,
clang::Parser::ParsedTemplateInfo const&, clang::Parser::ForRangeInit*)
/iusers/ekeane1/workspaces/llvm-project/clang/lib/Parse/ParseDecl.cpp:2257:37
#28 0x000000000781d0c4 clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&,
clang::DeclaratorContext, clang::SourceLocation*, clang::Parser::ForRangeInit*)
/iusers/ekeane1/workspaces/llvm-project/clang/lib/Parse/ParseDecl.cpp:1987:35
#29 0x00000000077ffa7e
clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange&,
clang::ParsingDeclSpec&, clang::AccessSpecifier)
/iusers/ekeane1/workspaces/llvm-project/clang/lib/Parse/Parser.cpp:1100:1
#30 0x00000000077ffb38
clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange&,
clang::ParsingDeclSpec*, clang::AccessSpecifier)
/iusers/ekeane1/workspaces/llvm-project/clang/lib/Parse/Parser.cpp:1115:57
#31 0x00000000077ff01a
clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange&,
clang::ParsingDeclSpec*) (.localalias.1) /iusers/ekeane1/workspaces/llvm-
project/clang/lib/Parse/Parser.cpp:935:58
#32 0x00000000077fe149
clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, bool)
/iusers/ekeane1/workspaces/llvm-project/clang/lib/Parse/Parser.cpp:683:42
#33 0x00000000077f9d4b clang::ParseAST(clang::Sema&, bool, bool)
/iusers/ekeane1/workspaces/llvm-project/clang/lib/Parse/ParseAST.cpp:158:37
#34 0x00000000056e7209 clang::ASTFrontendAction::ExecuteAction()
/iusers/ekeane1/workspaces/llvm-project/clang/lib/Frontend/FrontendAction.cpp:1057:11
#35 0x00000000056e6b71 clang::FrontendAction::Execute()
/iusers/ekeane1/workspaces/llvm-project/clang/lib/Frontend/FrontendAction.cpp:954:38
#36 0x0000000005681192
clang::CompilerInstance::ExecuteAction(clang::FrontendAction&)
/iusers/ekeane1/workspaces/llvm-project/clang/lib/Frontend/CompilerInstance.cpp:984:42
#37 0x000000000585d17c
clang::ExecuteCompilerInvocation(clang::CompilerInstance*)
/iusers/ekeane1/workspaces/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:278:38
#38 0x0000000002170cd6 cc1_main(llvm::ArrayRef<char const*>, char const*,
void*) /iusers/ekeane1/workspaces/llvm-
project/clang/tools/driver/cc1_main.cpp:240:40
#39 0x0000000002166c47 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&)
/iusers/ekeane1/workspaces/llvm-project/clang/tools/driver/driver.cpp:330:20
#40 0x0000000002167348 main /iusers/ekeane1/workspaces/llvm-
project/clang/tools/driver/driver.cpp:407:26
#41 0x00007fbad1f71c05 __libc_start_main (/lib64/libc.so.6+0x21c05)
#42 0x00000000021654e9 _start (./bin/clang+0x21654e9)
Aborted (core dumped)
The offending commit:
commit 00068c452a599c328986e8afcbb3311331d09d26
Author: Richard Smith <richard@metafoo.co.uk>
Date: Wed Jul 8 16:26:01 2020 -0700
Improve diagnostics for constant evaluation that fails because a
variable's initializer is not known.
The hope is that a better diagnostic for this case will reduce the rate
at which duplicates of non-bug PR41093 are reported.
Note, this MIGHT be a dupe of 46865
At the time of the crash:
(gdb) p VD->dump()
VarDecl 0x10faf700 parent 0x10f851f8 prev 0x10faf5a0 <cls_static03.cpp:12:20,
col:34> col:30 used y 'wchar_t &&' cinit
`-RecoveryExpr 0x10fafcd8 <col:34> '<dependent type>' contains-errors lvalue
`-DeclRefExpr 0x10faf870 <col:34> 'wchar_t':'wchar_t' lvalue Var 0x10faf4b0 'x' 'wchar_t':'wchar_t'
$1 = void
(gdb) p Init->dump()
RecoveryExpr 0x10fafcd8 '<dependent type>' contains-errors lvalue
`-DeclRefExpr 0x10faf870 'wchar_t':'wchar_t' lvalue Var 0x10faf4b0 'x'
'wchar_t':'wchar_t'
$2 = void
This looks like another case where we aren't properly handling a RecoveryExpr.
I applied https://reviews.llvm.org/D84637 and the problem still exists.
Presumably we need to bail out of evaluating the VarDeclInit if the Init is
invalid.
Ok, so the original report doesn't have anything to do with . It doesn't
involve recovery-exprs at all:
(gdb) p VD->dump()
VarDecl 0x10fc2630 <c6.cpp:63:15> col:15 implicit referenced box_chunk_size
'std::tuple_element<0, const std::tuple<unsigned int, unsigned int>>::type &'
cinit
`-CallExpr 0x10fc1a48 <col:15> 'const typename tuple_element<0UL,
tuple<unsigned int, unsigned int>>::type':'const unsigned int' lvalue adl
|-ImplicitCastExpr 0x10fc1a30 <col:15> 'const typename tuple_element<0UL, tuple<unsigned int, unsigned int>>::type &(*)(const tuple<unsigned int, unsigned int> &) noexcept' <FunctionToPointerDecay>
| `-DeclRefExpr 0x10fc1968 <col:15> 'const typename tuple_element<0UL, tuple<unsigned int, unsigned int>>::type &(const tuple<unsigned int, unsigned int> &) noexcept' lvalue Function 0x10fc1850 'get' 'const typename tuple_element<0UL, tuple<unsigned int, unsigned int>>::type &(const tuple<unsigned int, unsigned int> &) noexcept' (FunctionTemplate 0x10fb8190 'get')
`-ImplicitCastExpr 0x10fbe4c8 <col:15> 'const std::tuple<unsigned int, unsigned int>':'const std::tuple<unsigned int, unsigned int>' xvalue <NoOp>
`-DeclRefExpr 0x10fbe4a8 <col:15> 'const std::tuple<unsigned int, unsigned int>':'const std::tuple<unsigned int, unsigned int>' lvalue Decomposition 0x10fbc750 '' 'const std::tuple<unsigned int, unsigned int>':'const std::tuple<unsigned int, unsigned int>'
$1 = void
(gdb) p Init->dump()
CallExpr 0x10fc1a48 'const typename tuple_element<0UL, tuple<unsigned int,
unsigned int> >::type':'const unsigned int' lvalue adl
|-ImplicitCastExpr 0x10fc1a30 'const typename tuple_element<0UL, tuple<unsigned
int, unsigned int> >::type &(*)(const tuple<unsigned int, unsigned int> &)
noexcept' <FunctionToPointerDecay>
| `-DeclRefExpr 0x10fc1968 'const typename tuple_element<0UL, tuple<unsigned
int, unsigned int> >::type &(const tuple<unsigned int, unsigned int> &)
noexcept' lvalue Function 0x10fc1850 'get' 'const typename tuple_element<0UL,
tuple<unsigned int, unsigned int> >::type &(const tuple<unsigned int, unsigned
int> &) noexcept' (FunctionTemplate 0x10fb8190 'get')
`-ImplicitCastExpr 0x10fbe4c8 'const class std::tuple<unsigned int, unsigned
int>':'const class std::tuple<unsigned int, unsigned int>' xvalue <NoOp>
`-DeclRefExpr 0x10fbe4a8 'const class std::tuple<unsigned int, unsigned int>':'const class std::tuple<unsigned int, unsigned int>' lvalue Decomposition 0x10fbc750 '' 'const class std::tuple<unsigned int, unsigned int>':'const class std::tuple<unsigned int, unsigned int>'
$2 = void
(gdb)
This is valid in a constant expression because it is a reference. SO something
else is wrong with this.
SO I guess there are two bugs here now :/
Well, sorry to spam... but depending on the fix, I'm not sure there ARE two bugs here. My example fails the assert because the RecoveryExpr is a reference type as well.
Proposed a patch to fix this crash: https://reviews.llvm.org/D86649
c6.cpp
(2392 bytes, text/plain)c6-62bb79.cpp
(2422 bytes, text/plain)c6-62bb79.sh
(1966 bytes, text/plain)