This revision was automatically updated to reflect the committed changes. Closed by commit rL372361: [Consumed] Treat by-value class arguments as consuming by default, like rvalue… (authored by comex, committed by ). Herald added a project: LLVM. Herald added a subscriber: llvm-commits.
Changed prior to commit: https://reviews.llvm.org/D67743?vs=220778&id=220916#toc Repository: rL LLVM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D67743/new/ https://reviews.llvm.org/D67743 Files: cfe/trunk/lib/Analysis/Consumed.cpp cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp Index: cfe/trunk/lib/Analysis/Consumed.cpp =================================================================== --- cfe/trunk/lib/Analysis/Consumed.cpp +++ cfe/trunk/lib/Analysis/Consumed.cpp @@ -644,10 +644,10 @@ 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))) Index: cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp =================================================================== --- cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp +++ cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp @@ -53,12 +53,18 @@ 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 @@ 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 @@ 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 @@ 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}}
Index: cfe/trunk/lib/Analysis/Consumed.cpp =================================================================== --- cfe/trunk/lib/Analysis/Consumed.cpp +++ cfe/trunk/lib/Analysis/Consumed.cpp @@ -644,10 +644,10 @@ 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))) Index: cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp =================================================================== --- cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp +++ cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp @@ -53,12 +53,18 @@ 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 @@ 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 @@ 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 @@ 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}}
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits