]> granicus.if.org Git - clang/commitdiff
PR26111: segmentation fault with __attribute__((mode(QI))) on function declaration...
authorAlexey Bataev <a.bataev@hotmail.com>
Fri, 15 Jan 2016 04:36:32 +0000 (04:36 +0000)
committerAlexey Bataev <a.bataev@hotmail.com>
Fri, 15 Jan 2016 04:36:32 +0000 (04:36 +0000)
Allow "mode" attribute to be applied to VarDecl, not ValueDecl (which includes FunctionDecl and EnumConstantDecl), emit an error if this attribute is used with function declarations and enum constants.
Differential Revision: http://reviews.llvm.org/D16112

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

include/clang/AST/Decl.h
include/clang/Basic/Attr.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclAttr.cpp
test/Sema/attr-mode.c

index 029c1182f26e6a36bcfe5c1fb6d82d61b9b91b1e..29b19f2d8e384d62ad7eaf474fa04a808bbb1a8d 100644 (file)
@@ -1954,6 +1954,7 @@ public:
   unsigned getMinRequiredArguments() const;
 
   QualType getReturnType() const {
+    assert(getType()->getAs<FunctionType>() && "Expected a FunctionType!");
     return getType()->getAs<FunctionType>()->getReturnType();
   }
 
@@ -1964,6 +1965,7 @@ public:
 
   /// \brief Determine the type of an expression that calls this function.
   QualType getCallResultType() const {
+    assert(getType()->getAs<FunctionType>() && "Expected a FunctionType!");
     return getType()->getAs<FunctionType>()->getCallResultType(getASTContext());
   }
 
index 58a13f2f78f61a84e09df26f4e963d77f8f161e4..06228f2059ea38141475bc743c60a8a5fcf9a5a6 100644 (file)
@@ -879,6 +879,8 @@ def MipsInterrupt : InheritableAttr, TargetSpecificAttr<TargetMips> {
 
 def Mode : Attr {
   let Spellings = [GCC<"mode">];
+  let Subjects = SubjectList<[Var, TypedefName], ErrorDiag,
+                             "ExpectedVariableOrTypedef">;
   let Args = [IdentifierArgument<"Mode">];
   let Documentation = [Undocumented];
 }
index b59c9905e9cce5c76ee40c872c6e546d1c98bff1..d184b3692983ddb343d6b08703843207ce68bdba 100644 (file)
@@ -2851,8 +2851,6 @@ def warn_vector_mode_deprecated : Warning<
   InGroup<DeprecatedAttributes>;
 def err_complex_mode_vector_type : Error<
   "type of machine mode does not support base vector types">;
-def err_attr_wrong_decl : Error<
-  "%0 attribute invalid on this declaration, requires typedef or value">;
 def warn_attribute_nonnull_no_pointers : Warning<
   "'nonnull' attribute applied to function with no pointer arguments">,
   InGroup<IgnoredAttributes>;
index dcd7fd1ec48ec4f0c15e5d4ddf1c50466b8f5eac..f670b52d0d2c126c5a880dfb248bebbc9f089a90 100644 (file)
@@ -3391,13 +3391,8 @@ static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   QualType OldTy;
   if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
     OldTy = TD->getUnderlyingType();
-  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
-    OldTy = VD->getType();
-  else {
-    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
-      << Attr.getName() << Attr.getRange();
-    return;
-  }
+  else
+    OldTy = cast<VarDecl>(D)->getType();
 
   // Base type can also be a vector type (see PR17453).
   // Distinguish between base type and base element type.
@@ -3470,7 +3465,7 @@ static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
     TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy);
   else
-    cast<ValueDecl>(D)->setType(NewTy);
+    cast<VarDecl>(D)->setType(NewTy);
 
   D->addAttr(::new (S.Context)
              ModeAttr(Attr.getRange(), S.Context, Name,
index 49e41d210d035c865016706c1605a1140e9ab7f9..77bd2f737a4c92ae63d5c8ace0842e8c14ec768a 100644 (file)
@@ -24,6 +24,9 @@ typedef unsigned unwind_word __attribute((mode(unwind_word)));
 
 int **__attribute((mode(QI)))* i32;  // expected-error{{mode attribute}}
 
+__attribute__((mode(QI))) int invalid_func() { return 1; } // expected-error{{'mode' attribute only applies to variables and typedefs}}
+enum invalid_enum { A1 __attribute__((mode(QI))) }; // expected-error{{'mode' attribute only applies to variables and typedefs}}
+
 typedef _Complex double c32 __attribute((mode(SC)));
 int c32_test[sizeof(c32) == 8 ? 1 : -1];
 typedef _Complex float c64 __attribute((mode(DC)));