ygao added you to the CC list for the revision "fixing clang assertion failure
when creating illegal vector types".
Hi,
When compiling the following test cases, clang hits assertion error:
```
/* test1.c
* clang::ASTContext::getVectorType(): Assertion `vecType->isBuiltinType()'
failed.
*/
enum { e } x __attribute__((__vector_size__(64))); // enum cannot be the element
// type of a vector
/* end of test1 */
```
```
/* test2.c
* llvm::VectorType::get(): Assertion `NumElements > 0 &&
* "#Elements of a VectorType must be greater than 0"' failed.
*/
__attribute__((__vector_size__(1024))) signed char a; // vector size too large
/* end of test2 */
```
Both of them are error cases, but it would be nicer for clang to issue an error
message instead
of assertion failures. My patch attempts to detect each case and issue error
messages.
Would appreciate it if someone could review and commit this for me.
Many thanks,
- Gao.
http://llvm-reviews.chandlerc.com/D1214
Files:
include/clang/AST/Type.h
lib/Sema/SemaType.cpp
test/Sema/types.c
Index: include/clang/AST/Type.h
===================================================================
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1315,6 +1315,8 @@
/// NumElements - The number of elements in the vector.
unsigned NumElements : 29 - NumTypeBits;
+
+ enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 };
};
class AttributedTypeBitfields {
@@ -2524,6 +2526,9 @@
QualType getElementType() const { return ElementType; }
unsigned getNumElements() const { return VectorTypeBits.NumElements; }
+ static bool isVectorSizeTooLarge(unsigned NumElements) {
+ return NumElements > VectorTypeBitfields::MaxNumElements;
+ }
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -4522,6 +4522,12 @@
Attr.setInvalid();
return;
}
+ // The base type cannot be enum.
+ if (!CurType->isBuiltinType()) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
+ Attr.setInvalid();
+ return;
+ }
unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
// vecSize is specified in bytes - convert to bits.
unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
@@ -4533,6 +4539,12 @@
Attr.setInvalid();
return;
}
+ if (VectorType::isVectorSizeTooLarge(vectorSize / typeSize)) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_size_too_large)
+ << sizeExpr->getSourceRange();
+ Attr.setInvalid();
+ return;
+ }
if (vectorSize == 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
<< sizeExpr->getSourceRange();
Index: test/Sema/types.c
===================================================================
--- test/Sema/types.c
+++ test/Sema/types.c
@@ -64,3 +64,9 @@
void test2(int i) {
char c = (char __attribute__((may_alias))) i;
}
+
+// vector size too large
+int __attribute__ ((vector_size(8192))) x1; // expected-error {{vector size
too large}}
+
+// no support for vector enum type
+enum { e_2 } x2 __attribute__((vector_size(64))); // expected-error {{invalid
vector element type}}
Index: include/clang/AST/Type.h
===================================================================
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1315,6 +1315,8 @@
/// NumElements - The number of elements in the vector.
unsigned NumElements : 29 - NumTypeBits;
+
+ enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 };
};
class AttributedTypeBitfields {
@@ -2524,6 +2526,9 @@
QualType getElementType() const { return ElementType; }
unsigned getNumElements() const { return VectorTypeBits.NumElements; }
+ static bool isVectorSizeTooLarge(unsigned NumElements) {
+ return NumElements > VectorTypeBitfields::MaxNumElements;
+ }
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -4522,6 +4522,12 @@
Attr.setInvalid();
return;
}
+ // The base type cannot be enum.
+ if (!CurType->isBuiltinType()) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
+ Attr.setInvalid();
+ return;
+ }
unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
// vecSize is specified in bytes - convert to bits.
unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
@@ -4533,6 +4539,12 @@
Attr.setInvalid();
return;
}
+ if (VectorType::isVectorSizeTooLarge(vectorSize / typeSize)) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_size_too_large)
+ << sizeExpr->getSourceRange();
+ Attr.setInvalid();
+ return;
+ }
if (vectorSize == 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
<< sizeExpr->getSourceRange();
Index: test/Sema/types.c
===================================================================
--- test/Sema/types.c
+++ test/Sema/types.c
@@ -64,3 +64,9 @@
void test2(int i) {
char c = (char __attribute__((may_alias))) i;
}
+
+// vector size too large
+int __attribute__ ((vector_size(8192))) x1; // expected-error {{vector size too large}}
+
+// no support for vector enum type
+enum { e_2 } x2 __attribute__((vector_size(64))); // expected-error {{invalid vector element type}}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits