r199436 - Consumed analysis: bugfix for operator calls. Also fixes some formatting
DeLesley Hutchins
delesley at google.com
Thu Jan 16 15:07:16 PST 2014
Author: delesley
Date: Thu Jan 16 17:07:16 2014
New Revision: 199436
URL: http://llvm.org/viewvc/llvm-project?rev=199436&view=rev
Log:
Consumed analysis: bugfix for operator calls. Also fixes some formatting
issues, a few testcases, and kills fish.
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=199436&r1=199435&r2=199436&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/Consumed.cpp (original)
+++ cfe/trunk/lib/Analysis/Consumed.cpp Thu Jan 16 17:07:16 2014
@@ -183,11 +183,8 @@ static bool isKnownState(ConsumedState S
llvm_unreachable("invalid enum");
}
-static bool isRValueRefish(QualType ParamType) {
- return ParamType->isRValueReferenceType(); /* ||
- (ParamType->isLValueReferenceType() &&
- !cast<LValueReferenceType>(
- ParamType.getCanonicalType())->isSpelledAsLValue()); */
+static bool isRValueRef(QualType ParamType) {
+ return ParamType->isRValueReferenceType();
}
static bool isTestingFunction(const FunctionDecl *FunDecl) {
@@ -607,8 +604,8 @@ void ConsumedStmtVisitor::checkCallabili
bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg,
const FunctionDecl *FunD) {
unsigned Offset = 0;
- if (isa<CXXMethodDecl>(FunD))
- Offset = 1; // First argument to call is 'this' parameter
+ if (isa<CXXOperatorCallExpr>(Call) && isa<CXXMethodDecl>(FunD))
+ Offset = 1; // first argument is 'this'
// check explicit parameters
for (unsigned Index = Offset; Index < Call->getNumArgs(); ++Index) {
@@ -640,15 +637,14 @@ bool ConsumedStmtVisitor::handleCall(con
continue;
// Adjust state on the caller side.
- if (isRValueRefish(ParamType))
+ if (isRValueRef(ParamType))
setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Consumed);
else if (ReturnTypestateAttr *RT = Param->getAttr<ReturnTypestateAttr>())
setStateForVarOrTmp(StateMap, PInfo, mapReturnTypestateAttrState(RT));
- else if (isPointerOrRef(ParamType)) {
- if (!ParamType->getPointeeType().isConstQualified() ||
- isSetOnReadPtrType(ParamType))
- setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Unknown);
- }
+ else if (isPointerOrRef(ParamType) &&
+ (!ParamType->getPointeeType().isConstQualified() ||
+ isSetOnReadPtrType(ParamType)))
+ setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Unknown);
}
if (!ObjArg)
@@ -885,11 +881,11 @@ void ConsumedStmtVisitor::VisitParmVarDe
ParamState = mapParamTypestateAttrState(PTA);
else if (isConsumableType(ParamType))
ParamState = mapConsumableAttrState(ParamType);
- else if (isRValueRefish(ParamType) &&
- isConsumableType(ParamType->getPointeeType()))
+ else if (isRValueRef(ParamType) &&
+ isConsumableType(ParamType->getPointeeType()))
ParamState = mapConsumableAttrState(ParamType->getPointeeType());
else if (ParamType->isReferenceType() &&
- isConsumableType(ParamType->getPointeeType()))
+ isConsumableType(ParamType->getPointeeType()))
ParamState = consumed::CS_Unknown;
if (ParamState != CS_None)
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=199436&r1=199435&r2=199436&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp Thu Jan 16 17:07:16 2014
@@ -51,7 +51,7 @@ public:
class CONSUMABLE(unconsumed) DestructorTester {
public:
- DestructorTester() RETURN_TYPESTATE(unconsumed);
+ DestructorTester();
DestructorTester(int);
void operator*() CALLABLE_WHEN("unconsumed");
@@ -82,11 +82,21 @@ ConsumableClass<int> returnsUnknown() RE
void testInitialization() {
ConsumableClass<int> var0;
ConsumableClass<int> var1 = ConsumableClass<int>();
-
- var0 = ConsumableClass<int>();
-
+ ConsumableClass<int> var2(42);
+ ConsumableClass<int> var3(var2); // copy constructor
+ ConsumableClass<int> var4(var0); // copy consumed value
+
*var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
*var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
+ *var2;
+ *var3;
+ *var4; // expected-warning {{invalid invocation of method 'operator*' on object 'var4' while it is in the 'consumed' state}}
+
+ var0 = ConsumableClass<int>(42);
+ *var0;
+
+ var0 = var1;
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
if (var0.isValid()) {
*var0;
@@ -98,19 +108,16 @@ void testInitialization() {
}
void testDestruction() {
- DestructorTester D0(42), D1(42);
+ DestructorTester D0(42), D1(42), D2;
*D0;
*D1;
-
- DestructorTester D2;
- *D2;
+ *D2; // expected-warning {{invalid invocation of method 'operator*' on object 'D2' while it is in the 'consumed' state}}
D0.~DestructorTester(); // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}}
return; // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} \
- expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}} \
- expected-warning {{invalid invocation of method '~DestructorTester' on object 'D2' while it is in the 'unconsumed' state}}
+ expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}}
}
void testTempValue() {
@@ -427,6 +434,29 @@ void testParamTypestateCaller() {
testParamTypestateCallee(Var0, Var1); // expected-warning {{argument not in expected state; expected 'consumed', observed 'unconsumed'}}
}
+
+void consumeFunc(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+struct ParamTest {
+ static void consumeFuncStatic(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+ void consumeFuncMeth(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+ void operator<<(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+};
+
+void operator>>(ParamTest& pt, ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+
+
+void testFunctionParams() {
+ // Make sure we handle the different kinds of functions.
+ ConsumableClass<int> P;
+
+ consumeFunc(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+ ParamTest::consumeFuncStatic(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+ ParamTest pt;
+ pt.consumeFuncMeth(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+ pt << P; // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+ pt >> P; // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+}
+
void baf3(ConsumableClass<int> var) {
*var;
}
More information about the cfe-commits
mailing list