]> granicus.if.org Git - clang/commitdiff
add type attribute warn_unused, for -Wunused-variable warnings (pr#14253)
authorLubos Lunak <l.lunak@suse.cz>
Sat, 20 Jul 2013 15:05:36 +0000 (15:05 +0000)
committerLubos Lunak <l.lunak@suse.cz>
Sat, 20 Jul 2013 15:05:36 +0000 (15:05 +0000)
The functionality is equivalent to the GCC attribute. Variables of tagged
types will be warned about as unused if they are not used in any way
except for possible (even non-trivial) ctors/dtors called. Useful for tagging
classes like std::string (which is not part of this commit).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@186765 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Attr.td
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclAttr.cpp
test/SemaCXX/warn-unused-attribute.cpp [new file with mode: 0644]

index 8c820a0cf4e48e1286bfd9f5750185e5fffaa79b..eea99eb5351b4f1b7195d5d96817ad84df56c316 100644 (file)
@@ -749,6 +749,11 @@ def VecReturn : InheritableAttr {
   let Subjects = [CXXRecord];
 }
 
+def WarnUnused : InheritableAttr {
+  let Spellings = [GNU<"warn_unused">, CXX11<"gnu", "warn_unused">];
+  let Subjects = [Record];
+}
+
 def WarnUnusedResult : InheritableAttr {
   let Spellings = [GNU<"warn_unused_result">,
                    CXX11<"clang", "warn_unused_result">,
index 2291fc208fb91f573aefbad30c1ccffd4baeff36..53303e75d37655b97ad0b2941454025740f3df39 100644 (file)
@@ -1320,7 +1320,7 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) {
         return false;
 
       if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Tag)) {
-        if (!RD->hasTrivialDestructor())
+        if (!RD->hasTrivialDestructor() && !RD->hasAttr<WarnUnusedAttr>())
           return false;
 
         if (const Expr *Init = VD->getInit()) {
@@ -1330,7 +1330,7 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) {
             dyn_cast<CXXConstructExpr>(Init);
           if (Construct && !Construct->isElidable()) {
             CXXConstructorDecl *CD = Construct->getConstructor();
-            if (!CD->isTrivial())
+            if (!CD->isTrivial() && !RD->hasAttr<WarnUnusedAttr>())
               return false;
           }
         }
index ef401c3a4da6233412822a6c3715b5fc30eb9c72..a3e05e69d2a732474f6b852caf3d591e0c6d1b63 100644 (file)
@@ -2668,6 +2668,17 @@ static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
                           Attr.getAttributeSpellingListIndex()));
 }
 
+static void handleWarnUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  // Check the attribute arguments.
+  if (!checkAttributeNumArgs(S, Attr, 0))
+    return;
+
+  if (RecordDecl *RD = dyn_cast<RecordDecl>(D))
+    RD->addAttr(::new (S.Context) WarnUnusedAttr(Attr.getRange(), S.Context));
+  else
+    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+}
+
 static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
   // check the attribute arguments.
   if (!checkAttributeNumArgs(S, Attr, 0))
@@ -4892,6 +4903,9 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
   case AttributeList::AT_TypeVisibility:
     handleVisibilityAttr(S, D, Attr, true);
     break;
+  case AttributeList::AT_WarnUnused:
+    handleWarnUnusedAttr(S, D, Attr);
+    break;
   case AttributeList::AT_WarnUnusedResult: handleWarnUnusedResult(S, D, Attr);
     break;
   case AttributeList::AT_Weak:        handleWeakAttr        (S, D, Attr); break;
diff --git a/test/SemaCXX/warn-unused-attribute.cpp b/test/SemaCXX/warn-unused-attribute.cpp
new file mode 100644 (file)
index 0000000..72f96ee
--- /dev/null
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -verify %s
+struct __attribute__((warn_unused)) Test
+{
+    Test();
+    ~Test();
+    void use();
+};
+
+struct TestNormal
+{
+    TestNormal();
+};
+
+int main()
+{
+   Test unused;         // expected-warning {{unused variable 'unused'}}
+   Test used;
+   TestNormal normal;
+   used.use();
+}