]> granicus.if.org Git - clang/commitdiff
More Sema Check and a test case for init_priority attr.
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 18 Jun 2010 23:14:53 +0000 (23:14 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 18 Jun 2010 23:14:53 +0000 (23:14 +0000)
(radar 8076356).

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclAttr.cpp
test/SemaCXX/init-priority-attr.cpp [new file with mode: 0644]

index f736ab55fdd01d915fa7f9735c01091d9113a765..5665cf0c87b0fc8c67fbd97a17af05cd3b73981b 100644 (file)
@@ -818,6 +818,9 @@ def err_attribute_argument_not_int : Error<
 def err_attribute_argument_outof_range : Error<
   "init_priority attribute requires integer constant between "
   "101 and 65535 inclusive">;
+def err_init_priority_object_attr : Error<
+  "can only use ‘init_priority’ attribute on file-scope definitions "
+  "of objects of class type">;
 def err_attribute_argument_n_not_int : Error<
   "'%0' attribute requires parameter %1 to be an integer constant">;
 def err_attribute_argument_n_not_string : Error<
index b54bc1ed9f52dba6120e2a570905623fe5eeefd4..c5eb048577a467a5567ae7fd54be729033f975d6 100644 (file)
@@ -1189,12 +1189,27 @@ static void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr,
     return;
   }
   
+  if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) {
+    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
+    Attr.setInvalid();
+    return;
+  }
+  QualType T = dyn_cast<VarDecl>(d)->getType();
+  if (S.Context.getAsArrayType(T))
+    T = S.Context.getBaseElementType(T);
+  if (!T->getAs<RecordType>()) {
+    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
+    Attr.setInvalid();
+    return;
+  }
+  
   if (Attr.getNumArgs() != 1) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
     Attr.setInvalid();
     return;
   }
   Expr *priorityExpr = static_cast<Expr *>(Attr.getArg(0));
+  
   llvm::APSInt priority(32);
   if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
       !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
diff --git a/test/SemaCXX/init-priority-attr.cpp b/test/SemaCXX/init-priority-attr.cpp
new file mode 100644 (file)
index 0000000..6ea263d
--- /dev/null
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class Two {
+private:
+    int i, j, k;
+public:
+    static int count;
+    Two( int ii, int jj ) { i = ii; j = jj; k = count++; };
+    Two( void )           { i =  0; j =  0; k = count++; };
+    int eye( void ) { return i; };
+    int jay( void ) { return j; };
+    int kay( void ) { return k; };
+};
+
+extern Two foo;
+extern Two goo;
+extern Two coo[];
+extern Two koo[];
+
+Two foo __attribute__((init_priority(101))) ( 5, 6 );
+
+Two goo __attribute__((init_priority(2,3))) ( 5, 6 ); // expected-error {{attribute requires 1 argument(s)}}
+
+Two coo[2]  __attribute__((init_priority(3))); // expected-error {{init_priority attribute requires integer constant between 101 and 65535 inclusive}}
+
+Two koo[4]  __attribute__((init_priority(1.13))); // expected-error {{'init_priority' attribute requires integer constant}}
+
+
+Two func()  __attribute__((init_priority(1001))); // expected-error {{can only use ‘init_priority’ attribute on file-scope definitions of objects of class type}}
+
+int i  __attribute__((init_priority(1001))); // expected-error {{can only use ‘init_priority’ attribute on file-scope definitions of objects of class type}}
+
+int main() {
+       Two foo __attribute__((init_priority(1001)));   // expected-error {{can only use ‘init_priority’ attribute on file-scope definitions of objects of class type}}
+}
+