summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2016-01-15 04:36:32 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2016-01-15 04:36:32 +0000
commit2c485a700322e73783bc6543e419fbb861fcb768 (patch)
tree4074303a211ffb87ac8669b27735bb42e762dd23
parentd51e9933b6aaa6d99efe871bf6a73c0484e317b9 (diff)
downloadbcm5719-llvm-2c485a700322e73783bc6543e419fbb861fcb768.tar.gz
bcm5719-llvm-2c485a700322e73783bc6543e419fbb861fcb768.zip
PR26111: segmentation fault with __attribute__((mode(QI))) on function declaration, by Denis Zobnin
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 llvm-svn: 257868
-rw-r--r--clang/include/clang/AST/Decl.h2
-rw-r--r--clang/include/clang/Basic/Attr.td2
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp11
-rw-r--r--clang/test/Sema/attr-mode.c3
5 files changed, 10 insertions, 10 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 029c1182f26..29b19f2d8e3 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -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());
}
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 58a13f2f78f..06228f2059e 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -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];
}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b59c9905e9c..d184b369298 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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>;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index dcd7fd1ec48..f670b52d0d2 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -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,
diff --git a/clang/test/Sema/attr-mode.c b/clang/test/Sema/attr-mode.c
index 49e41d210d0..77bd2f737a4 100644
--- a/clang/test/Sema/attr-mode.c
+++ b/clang/test/Sema/attr-mode.c
@@ -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)));
OpenPOWER on IntegriCloud