[PATCH] Re-adding the isSpelledAsLValue check in Consumed analysis
Chris Wailes
chris.wailes at gmail.com
Mon Feb 24 13:53:53 PST 2014
Hi delesley, aaron.ballman,
This patch adds a isSpelledAsLValue check back into the Consumed analysis, as well as adding a test to show its necessity.
http://llvm-reviews.chandlerc.com/D2872
Files:
lib/Analysis/Consumed.cpp
test/SemaCXX/warn-consumed-analysis.cpp
Index: lib/Analysis/Consumed.cpp
===================================================================
--- lib/Analysis/Consumed.cpp
+++ lib/Analysis/Consumed.cpp
@@ -183,8 +183,10 @@
llvm_unreachable("invalid enum");
}
-static bool isRValueRef(QualType ParamType) {
- return ParamType->isRValueReferenceType();
+static bool isLikeRValueRef(QualType ParamType) {
+ return ParamType->isRValueReferenceType() ||
+ (ParamType->isLValueReferenceType() &&
+ !cast<LValueReferenceType>(ParamType)->isSpelledAsLValue());
}
static bool isTestingFunction(const FunctionDecl *FunDecl) {
@@ -637,7 +639,7 @@
continue;
// Adjust state on the caller side.
- if (isRValueRef(ParamType))
+ if (isLikeRValueRef(ParamType))
setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Consumed);
else if (ReturnTypestateAttr *RT = Param->getAttr<ReturnTypestateAttr>())
setStateForVarOrTmp(StateMap, PInfo, mapReturnTypestateAttrState(RT));
@@ -881,7 +883,7 @@
ParamState = mapParamTypestateAttrState(PTA);
else if (isConsumableType(ParamType))
ParamState = mapConsumableAttrState(ParamType);
- else if (isRValueRef(ParamType) &&
+ else if (isLikeRValueRef(ParamType) &&
isConsumableType(ParamType->getPointeeType()))
ParamState = mapConsumableAttrState(ParamType->getPointeeType());
else if (ParamType->isReferenceType() &&
Index: test/SemaCXX/warn-consumed-analysis.cpp
===================================================================
--- test/SemaCXX/warn-consumed-analysis.cpp
+++ test/SemaCXX/warn-consumed-analysis.cpp
@@ -11,6 +11,16 @@
typedef decltype(nullptr) nullptr_t;
+template <class T> struct remove_reference {typedef T type;};
+template <class T> struct remove_reference<T&> {typedef T type;};
+template <class T> struct remove_reference<T&&> {typedef T type;};
+
+template<class T>
+typename remove_reference<T>::type&& move(T&& a) noexcept {
+ typedef typename remove_reference<T>::type&& RvalRef;
+ return static_cast<RvalRef>(a);
+}
+
template <typename T>
class CONSUMABLE(unconsumed) ConsumableClass {
T var;
@@ -135,6 +145,11 @@
*var0;
*var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
+
+ var1 = move(var0);
+
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
+ *var1;
}
void testIfStmt() {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2872.1.patch
Type: text/x-patch
Size: 2497 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140224/2ad57cf8/attachment.bin>
More information about the cfe-commits
mailing list