From ba101e1b3b0e819431cf68369053b73c599a91f8 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Fri, 30 Nov 2012 01:15:32 +0000 Subject: [PATCH] Use the new LLVM_LVALUE_FUNCTION to ban two getAs() calls on rvalues. If 'x' is a temporary, x.getAs() may not be safe if the result is supposed to persist (if its address is stored somewhere). Since getAs() can return a null value, the result is almost always stored into a variable, which of course is not safe when the original value dies. This has caused several bugs with GCC's "Temporaries May Vanish Sooner Than You Expect" optimization; in C++11 builds, at least, we'll be able to catch these problems now. I would suggest applying these to other getAs() and get*As() methods (castAs is "better" because sometimes the result is used directly, which means the temporary will still be live), but these two have both caused trouble in the analyzer in the past. llvm-svn: 168967 --- clang/include/clang/Analysis/CFG.h | 10 ++++++---- .../StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h | 9 ++++++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Analysis/CFG.h b/clang/include/clang/Analysis/CFG.h index 8cc5d814e822..5fcd64c76cd3 100644 --- a/clang/include/clang/Analysis/CFG.h +++ b/clang/include/clang/Analysis/CFG.h @@ -83,11 +83,13 @@ public: operator bool() const { return isValid(); } - template const ElemTy *getAs() const { - if (llvm::isa(this)) - return static_cast(this); - return 0; + template const ElemTy *getAs() const LLVM_LVALUE_FUNCTION { + return dyn_cast(this); } + +#if LLVM_USE_RVALUE_REFERENCES + template void getAs() && LLVM_DELETED_FUNCTION; +#endif }; class CFGStmt : public CFGElement { diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h index b112e66d30d3..ebdb02dd22df 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -155,7 +155,14 @@ public: ProgramStateRef getState() const { return State; } template - const T* getLocationAs() const { return llvm::dyn_cast(&Location); } + const T* getLocationAs() const LLVM_LVALUE_FUNCTION { + return dyn_cast(&Location); + } + +#if LLVM_USE_RVALUE_REFERENCES + template + void getLocationAs() && LLVM_DELETED_FUNCTION; +#endif static void Profile(llvm::FoldingSetNodeID &ID, const ProgramPoint &Loc,