aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-11-30 01:15:32 +0000
committerJordan Rose <jordan_rose@apple.com>2012-11-30 01:15:32 +0000
commitdcd42fbb418cf662c136cb035e235a44b58ad91e (patch)
treed97ab6a7cf9ccb8b31465e08a7bd301eb8d68dc0 /include/clang
parent7dff05bf3019995798def5d1066e4282b8578df6 (diff)
Use the new LLVM_LVALUE_FUNCTION to ban two getAs() calls on rvalues.
If 'x' is a temporary, x.getAs<Foo>() 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168967 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/Analysis/CFG.h10
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h9
2 files changed, 14 insertions, 5 deletions
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index 8cc5d814e8..5fcd64c76c 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -83,11 +83,13 @@ public:
operator bool() const { return isValid(); }
- template<class ElemTy> const ElemTy *getAs() const {
- if (llvm::isa<ElemTy>(this))
- return static_cast<const ElemTy*>(this);
- return 0;
+ template<class ElemTy> const ElemTy *getAs() const LLVM_LVALUE_FUNCTION {
+ return dyn_cast<ElemTy>(this);
}
+
+#if LLVM_USE_RVALUE_REFERENCES
+ template<class ElemTy> void getAs() && LLVM_DELETED_FUNCTION;
+#endif
};
class CFGStmt : public CFGElement {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index b112e66d30..ebdb02dd22 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -155,7 +155,14 @@ public:
ProgramStateRef getState() const { return State; }
template <typename T>
- const T* getLocationAs() const { return llvm::dyn_cast<T>(&Location); }
+ const T* getLocationAs() const LLVM_LVALUE_FUNCTION {
+ return dyn_cast<T>(&Location);
+ }
+
+#if LLVM_USE_RVALUE_REFERENCES
+ template <typename T>
+ void getLocationAs() && LLVM_DELETED_FUNCTION;
+#endif
static void Profile(llvm::FoldingSetNodeID &ID,
const ProgramPoint &Loc,