george.karpenkov created this revision. Herald added subscribers: szepet, xazax.hun, javed.absar.
Fixes https://bugs.llvm.org/show_bug.cgi?id=30565 @dcoughlin Any advice on how to handle different stdlib implementations? Can we conjure a separate symbol instead of relying on a particular struct layout? For now this implementation will simply not go inside a differently implemented `call_once`. https://reviews.llvm.org/D38702 Files: lib/Analysis/BodyFarm.cpp test/Analysis/call_once.cpp Index: test/Analysis/call_once.cpp =================================================================== --- test/Analysis/call_once.cpp +++ test/Analysis/call_once.cpp @@ -231,3 +231,12 @@ int x = call_once(); clang_analyzer_eval(x == 5); // expected-warning{{TRUE}} } + +namespace std { +template <typename d, typename e> +void call_once(d, e); +} +void g(); +void test_no_segfault_on_different_impl() { + std::call_once(g, false); // no-warning +} Index: lib/Analysis/BodyFarm.cpp =================================================================== --- lib/Analysis/BodyFarm.cpp +++ lib/Analysis/BodyFarm.cpp @@ -362,6 +362,12 @@ /* GetNonReferenceType=*/true); CXXRecordDecl *FlagCXXDecl = FlagType->getAsCXXRecordDecl(); + if (FlagCXXDecl == nullptr) { + DEBUG(llvm::dbgs() << "Flag field is not a CXX record: " + << "unknown std::call_once implementation." + << "Ignoring the call.\n"); + return nullptr; + } // Note: here we are assuming libc++ implementation of call_once, // which has a struct with a field `__state_`.
Index: test/Analysis/call_once.cpp =================================================================== --- test/Analysis/call_once.cpp +++ test/Analysis/call_once.cpp @@ -231,3 +231,12 @@ int x = call_once(); clang_analyzer_eval(x == 5); // expected-warning{{TRUE}} } + +namespace std { +template <typename d, typename e> +void call_once(d, e); +} +void g(); +void test_no_segfault_on_different_impl() { + std::call_once(g, false); // no-warning +} Index: lib/Analysis/BodyFarm.cpp =================================================================== --- lib/Analysis/BodyFarm.cpp +++ lib/Analysis/BodyFarm.cpp @@ -362,6 +362,12 @@ /* GetNonReferenceType=*/true); CXXRecordDecl *FlagCXXDecl = FlagType->getAsCXXRecordDecl(); + if (FlagCXXDecl == nullptr) { + DEBUG(llvm::dbgs() << "Flag field is not a CXX record: " + << "unknown std::call_once implementation." + << "Ignoring the call.\n"); + return nullptr; + } // Note: here we are assuming libc++ implementation of call_once, // which has a struct with a field `__state_`.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits