Consumed analysis: switch from tests_consumed/unconsumed to a general
tests_typestate attribute. Patch by chris.wailes@gmail.com.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192513 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index 53e53b2..88b7dc4 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -1501,15 +1501,6 @@
Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
}
- void warnUnnecessaryTest(StringRef VariableName, StringRef VariableState,
- SourceLocation Loc) {
-
- PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unnecessary_test) <<
- VariableName << VariableState);
-
- Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
- }
-
void warnUseOfTempInInvalidState(StringRef MethodName, StringRef State,
SourceLocation Loc) {
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 1985de4..a07d6ca 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -1079,24 +1079,11 @@
States.size(), Attr.getAttributeSpellingListIndex()));
}
-static void handleTestsConsumedAttr(Sema &S, Decl *D,
- const AttributeList &Attr) {
- if (!isa<CXXMethodDecl>(D)) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
- Attr.getName() << ExpectedMethod;
- return;
- }
-
- if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
- return;
-
- D->addAttr(::new (S.Context)
- TestsConsumedAttr(Attr.getRange(), S.Context,
- Attr.getAttributeSpellingListIndex()));
-}
-static void handleTestsUnconsumedAttr(Sema &S, Decl *D,
- const AttributeList &Attr) {
+static void handleTestsTypestateAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ if (!checkAttributeNumArgs(S, Attr, 1)) return;
+
if (!isa<CXXMethodDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
Attr.getName() << ExpectedMethod;
@@ -1106,9 +1093,29 @@
if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
return;
+ TestsTypestateAttr::ConsumedState TestState;
+
+ if (Attr.isArgIdent(0)) {
+ StringRef Param = Attr.getArgAsIdent(0)->Ident->getName();
+
+ if (Param == "consumed") {
+ TestState = TestsTypestateAttr::Consumed;
+ } else if (Param == "unconsumed") {
+ TestState = TestsTypestateAttr::Unconsumed;
+ } else {
+ S.Diag(Attr.getLoc(), diag::warn_invalid_test_typestate) << Param;
+ return;
+ }
+
+ } else {
+ S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
+ Attr.getName() << AANT_ArgumentIdentifier;
+ return;
+ }
+
D->addAttr(::new (S.Context)
- TestsUnconsumedAttr(Attr.getRange(), S.Context,
- Attr.getAttributeSpellingListIndex()));
+ TestsTypestateAttr(Attr.getRange(), S.Context, TestState,
+ Attr.getAttributeSpellingListIndex()));
}
static void handleReturnTypestateAttr(Sema &S, Decl *D,
@@ -4782,7 +4789,7 @@
handleAcquiredAfterAttr(S, D, Attr);
break;
- // Uniqueness analysis attributes.
+ // Consumed analysis attributes.
case AttributeList::AT_Consumable:
handleConsumableAttr(S, D, Attr);
break;
@@ -4792,11 +4799,8 @@
case AttributeList::AT_CallableWhen:
handleCallableWhenAttr(S, D, Attr);
break;
- case AttributeList::AT_TestsConsumed:
- handleTestsConsumedAttr(S, D, Attr);
- break;
- case AttributeList::AT_TestsUnconsumed:
- handleTestsUnconsumedAttr(S, D, Attr);
+ case AttributeList::AT_TestsTypestate:
+ handleTestsTypestateAttr(S, D, Attr);
break;
case AttributeList::AT_ReturnTypestate:
handleReturnTypestateAttr(S, D, Attr);