Skip to content

Commit

Permalink
Add more error checking to attribute vecreturn
Browse files Browse the repository at this point in the history
llvm-svn: 114251
  • Loading branch information
jtsoftware committed Sep 18, 2010
1 parent 8ea46b6 commit 9a587aa
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 1 deletion.
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,10 @@ def warn_function_attribute_wrong_type : Warning<
def warn_gnu_inline_attribute_requires_inline : Warning<
"'gnu_inline' attribute requires function to be marked 'inline',"
" attribute ignored">;
def err_attribute_vecreturn_only_vector_member : Error<
"the vecreturn attribute can only be used on a class or structure with one member, which must be a vector">;
def err_attribute_vecreturn_only_pod_record : Error<
"the vecreturn attribute can only be used on a POD (plain old data) class or structure (i.e. no virtual functions)">;
def err_cconv_change : Error<
"function declared '%0' here was previously declared "
"%select{'%2'|without calling convention}1">;
Expand Down
23 changes: 22 additions & 1 deletion clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ static void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
return result; // This will be returned in a register
}
*/
if (!isa<CXXRecordDecl>(d)) {
if (!isa<RecordDecl>(d)) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
<< Attr.getName() << 9 /*class*/;
return;
Expand All @@ -735,6 +735,27 @@ static void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
return;
}

RecordDecl *record = cast<RecordDecl>(d);
int count = 0;

if (!isa<CXXRecordDecl>(record)) {
S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
return;
}

if (!cast<CXXRecordDecl>(record)->isPOD()) {
S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
return;
}

for (RecordDecl::field_iterator iter = record->field_begin(); iter != record->field_end(); iter++) {
if ((count == 1) || !iter->getType()->isVectorType()) {
S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
return;
}
count++;
}

d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
}

Expand Down
17 changes: 17 additions & 0 deletions clang/test/Parser/cxx-altivec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,20 @@ Vector Add(Vector lhs, Vector rhs)
result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
return result; // This will (eventually) be returned in a register
}

// vecreturn attribute test - should error because of virtual function.
class VectorClassNonPod
{
__vector float xyzw;
public:
VectorClassNonPod() {}
virtual ~VectorClassNonPod() {}
} __attribute__((vecreturn)); // expected-error {{the vecreturn attribute can only be used on a POD (plain old data) class or structure (i.e. no virtual functions)}}

// vecreturn attribute test - should error because of virtual function.
class VectorClassMultipleMembers
{
public:
__vector float xyzw;
__vector float abcd;
} __attribute__((vecreturn)); // expected-error {{the vecreturn attribute can only be used on a class or structure with one member, which must be a vector}}

0 comments on commit 9a587aa

Please sign in to comment.