[cfe-dev] clang::Sema::ActOnFinishFunctionBody() "Leftover expressions for odr-use checking" assertion

Azat Khuzhin a3at.mail at gmail.com
Tue Feb 24 15:08:28 PST 2015


On Wed, Feb 18, 2015 at 03:15:18AM +0300, Azat Khuzhin wrote:
> Hi all,
> 
> During playing with clang library, I got the next assertion:
> /src/oss/clang/lib/Sema/SemaDecl.cpp:10637: clang::Decl* clang::Sema::ActOnFinishFunctionBody(clang::Decl*, clang::Stmt*, bool): Assertion `MaybeODRUseExprs.empty() && "Leftover expressions for odr-use checking"' failed.
> 
> Here is backtrace:
> Program received signal SIGABRT, Aborted.
> 0x00007fffdddef107 in __GI_raise (sig=sig at entry=6) at raise.c:56
> 56      raise.c: No such file or directory.
> (gdb) bt
> #0  0x00007fffdddef107 in __GI_raise (sig=sig at entry=6) at raise.c:56
> #1  0x00007fffdddf04e8 in __GI_abort () at abort.c:89
> #2  0x00007fffddde8226 in __assert_fail_base (fmt=0x7fffddf1e968 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion at entry=0x7ffff679c9c0 "MaybeODRUseExprs.empty() && \"Leftover expressions for odr-use checking\"", 
>     file=file at entry=0x7ffff679b888 "/src/oss/clang/lib/Sema/SemaDecl.cpp", line=line at entry=10637, 
>     function=function at entry=0x7ffff67ac480 <clang::Sema::ActOnFinishFunctionBody(clang::Decl*, clang::Stmt*, bool)::__PRETTY_FUNCTION__> "clang::Decl* clang::Sema::ActOnFinishFunctionBody(clang::Decl*, clang::Stmt*, bool)") at assert.c:92
> #3  0x00007fffddde82d2 in __GI___assert_fail (assertion=0x7ffff679c9c0 "MaybeODRUseExprs.empty() && \"Leftover expressions for odr-use checking\"", file=0x7ffff679b888 "/src/oss/clang/lib/Sema/SemaDecl.cpp", line=10637, 
>     function=0x7ffff67ac480 <clang::Sema::ActOnFinishFunctionBody(clang::Decl*, clang::Stmt*, bool)::__PRETTY_FUNCTION__> "clang::Decl* clang::Sema::ActOnFinishFunctionBody(clang::Decl*, clang::Stmt*, bool)") at assert.c:101
> #4  0x00007ffff62062f5 in clang::Sema::ActOnFinishFunctionBody(clang::Decl*, clang::Stmt*, bool) () from /src/oss/llvm/.cmake/lib/libclangSema.so
> #5  0x00007ffff6204fd9 in clang::Sema::ActOnFinishFunctionBody(clang::Decl*, clang::Stmt*) () from /src/oss/llvm/.cmake/lib/libclangSema.so
> #6  0x00007ffff4dbcc52 in clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) () from /src/oss/llvm/.cmake/lib/libclangParse.so
> #7  0x00007ffff4dd65d3 in clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*) () from /src/oss/llvm/.cmake/lib/libclangParse.so
> #8  0x00007ffff4d54446 in clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, unsigned int, clang::SourceLocation*, clang::Parser::ForRangeInit*) () from /src/oss/llvm/.cmake/lib/libclangParse.so
> #9  0x00007ffff4dd58e4 in clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec&, clang::AccessSpecifier) () from /src/oss/llvm/.cmake/lib/libclangParse.so
> #10 0x00007ffff4dd599c in clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*, clang::AccessSpecifier) () from /src/oss/llvm/.cmake/lib/libclangParse.so
> #11 0x00007ffff4dd5102 in clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*) () from /src/oss/llvm/.cmake/lib/libclangParse.so
> #12 0x00007ffff4d6beee in clang::Parser::ParseInnerNamespace(std::vector<clang::SourceLocation, std::allocator<clang::SourceLocation> >&, std::vector<clang::IdentifierInfo*, std::allocator<clang::IdentifierInfo*> >&, std::vector<clang::SourceLocation, std::allocator<clang::
> SourceLocation> >&, unsigned int, clang::SourceLocation&, clang::ParsedAttributes&, clang::BalancedDelimiterTracker&) () from /src/oss/llvm/.cmake/lib/libclangParse.so
> #13 0x00007ffff4d6bd57 in clang::Parser::ParseNamespace(unsigned int, clang::SourceLocation&, clang::SourceLocation) () from /src/oss/llvm/.cmake/lib/libclangParse.so
> #14 0x00007ffff4d536d2 in clang::Parser::ParseDeclaration(unsigned int, clang::SourceLocation&, clang::Parser::ParsedAttributesWithRange&) () from /src/oss/llvm/.cmake/lib/libclangParse.so
> #15 0x00007ffff4dd4d8e in clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*) () from /src/oss/llvm/.cmake/lib/libclangParse.so
> #16 0x00007ffff4dd468a in clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&) () from /src/oss/llvm/.cmake/lib/libclangParse.so
> #17 0x00007ffff4d3ce3f in clang::ParseAST(clang::Sema&, bool, bool) () from /src/oss/llvm/.cmake/lib/libclangParse.so
> #18 0x00007ffff7a8a002 in clang::ASTFrontendAction::ExecuteAction() () from /src/oss/llvm/.cmake/lib/libclangFrontend.so
> #19 0x00007ffff7a89ab9 in clang::FrontendAction::Execute() () from /src/oss/llvm/.cmake/lib/libclangFrontend.so
> #20 0x00007ffff7a48ca5 in clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) () from /src/oss/llvm/.cmake/lib/libclangFrontend.so
> #21 0x00007ffff2d92d12 in clang::tooling::FrontendActionFactory::runInvocation(clang::CompilerInvocation*, clang::FileManager*, clang::DiagnosticConsumer*) () from /src/oss/llvm/.cmake/lib/libclangTooling.so
> #22 0x00007ffff2d92bf7 in clang::tooling::ToolInvocation::runInvocation(char const*, clang::driver::Compilation*, clang::CompilerInvocation*) () from /src/oss/llvm/.cmake/lib/libclangTooling.so
> #23 0x00007ffff2d92aaf in clang::tooling::ToolInvocation::run() () from /src/oss/llvm/.cmake/lib/libclangTooling.so
> ...
> 
> After debugging, I found the reason of a crash:
> /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/basic_string.h:2937:
> 
> And here is a sniplet from basic_string:
> 2932   inline string
> 2933   to_string(float __val)
> 2934   {  
> 2935     const int __n = 
> 2936       __gnu_cxx::__numeric_traits<float>::__max_exponent10 + 20;
> 2937     return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,                                
> 2938                                            "%f", __val);
> 2939   }
> 
> assert goes away if:
> - you replace __n with some const (i.e. 20)
> - add a cast to size_t for __n -- "(size_t)__n"
> 
> However clang compiler doesn't bail with this assert:
> $ cat /tmp/string.cpp
> #include <string>
> int main()
> {
>         std::string a("a");
>         a = std::to_string((float)1);
>         return a.length();
> };
> $ clang++ -std=c++11 /tmp/string.cpp # also tested using some of the next options: "-c" "-g3" "-O0" "-O3"
> $ clang++ --version
> clang version 3.7.0 (http://llvm.org/git/clang.git bd12ce7a3cfb1f36c0b5e21dc7fe6a5720c8f94e) (http://llvm.org/git/llvm.git 11ef7bf0d77043e1c8d2592a819a0b247449f464)
> Target: x86_64-unknown-linux-gnu
> Thread model: posix
> 
> clang revision: trunk at 226250
> llvm  revision: trunk at 226269
> 
> Could anybody explain why this may differs?
> And/or possible directions for debugging/patching?

After digging this issue for a while I finally have a patch that fixes this
issue, it passes clang regression tests (ninja check-clang) except
Frontend/source-col-map.c (but it fails before this patch too), and llvm tests
(ninja test/check).

Sure this patch must have helper function like ActOnCallExprError() or
something like this, and I will add this if the basic idea is good enough.
Therefore *I will be very appreciate if somebody from maintainers could have a
look*.
Also I'm currently working on reproducing this with 50L sample and a regression
test.

Thanks!
Azat.

Leftover-expressions-for-odr-use-checking.patch:
================================================
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 4183ae4..437ba3c 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -1459,6 +1459,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
              })) {
             (void)Actions.CorrectDelayedTyposInExpr(LHS);
             LHS = ExprError();
+            Actions.DiscardCleanupsInEvaluationContext();
           }
         }
       }



More information about the cfe-dev mailing list