r372361 - [Consumed] Treat by-value class arguments as consuming by default, like rvalue refs.
Nicholas Allegra via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 19 16:00:31 PDT 2019
Author: comex
Date: Thu Sep 19 16:00:31 2019
New Revision: 372361
URL: http://llvm.org/viewvc/llvm-project?rev=372361&view=rev
Log:
[Consumed] Treat by-value class arguments as consuming by default, like rvalue refs.
Differential Revision: https://reviews.llvm.org/D67743
Modified:
cfe/trunk/lib/Analysis/Consumed.cpp
cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp
Modified: cfe/trunk/lib/Analysis/Consumed.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Consumed.cpp?rev=372361&r1=372360&r2=372361&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/Consumed.cpp (original)
+++ cfe/trunk/lib/Analysis/Consumed.cpp Thu Sep 19 16:00:31 2019
@@ -644,10 +644,10 @@ bool ConsumedStmtVisitor::handleCall(con
continue;
// Adjust state on the caller side.
- if (isRValueRef(ParamType))
- setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Consumed);
- else if (ReturnTypestateAttr *RT = Param->getAttr<ReturnTypestateAttr>())
+ if (ReturnTypestateAttr *RT = Param->getAttr<ReturnTypestateAttr>())
setStateForVarOrTmp(StateMap, PInfo, mapReturnTypestateAttrState(RT));
+ else if (isRValueRef(ParamType) || isConsumableType(ParamType))
+ setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Consumed);
else if (isPointerOrRef(ParamType) &&
(!ParamType->getPointeeType().isConstQualified() ||
isSetOnReadPtrType(ParamType)))
Modified: cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp?rev=372361&r1=372360&r2=372361&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp Thu Sep 19 16:00:31 2019
@@ -53,12 +53,18 @@ class CONSUMABLE(unconsumed) DestructorT
public:
DestructorTester();
DestructorTester(int);
+ DestructorTester(nullptr_t) RETURN_TYPESTATE(unconsumed);
+ DestructorTester(DestructorTester &&);
void operator*() CALLABLE_WHEN("unconsumed");
~DestructorTester() CALLABLE_WHEN("consumed");
+
};
+void dtByVal(DestructorTester);
+void dtByValMarkUnconsumed(DestructorTester RETURN_TYPESTATE(unconsumed));
+
void baf0(const ConsumableClass<int> var);
void baf1(const ConsumableClass<int> &var);
void baf2(const ConsumableClass<int> *var);
@@ -120,6 +126,19 @@ void testDestruction() {
expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}}
}
+void testDestructionByVal() {
+ {
+ // both the var and the temporary are consumed:
+ DestructorTester D0(nullptr);
+ dtByVal((DestructorTester &&)D0);
+ }
+ {
+ // the var is consumed but the temporary isn't:
+ DestructorTester D1(nullptr);
+ dtByValMarkUnconsumed((DestructorTester &&)D1); // expected-warning {{invalid invocation of method '~DestructorTester' on a temporary object while it is in the 'unconsumed' state}}
+ }
+}
+
void testTempValue() {
*ConsumableClass<int>(); // expected-warning {{invalid invocation of method 'operator*' on a temporary object while it is in the 'consumed' state}}
}
@@ -413,10 +432,15 @@ void testParamReturnTypestateCallee(bool
Param.consume();
}
+void testRvalueRefParamReturnTypestateCallee(ConsumableClass<int> &&Param RETURN_TYPESTATE(unconsumed)) {
+ Param.unconsume();
+}
+
void testParamReturnTypestateCaller() {
ConsumableClass<int> var;
testParamReturnTypestateCallee(true, var);
+ testRvalueRefParamReturnTypestateCallee((ConsumableClass<int> &&)var);
*var;
}
@@ -480,6 +504,9 @@ void testCallingConventions() {
baf2(&var);
*var;
+
+ baf3(var);
+ *var;
baf4(var);
*var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
More information about the cfe-commits
mailing list