let SemaHandler = 0;
}
-def AllocSize : InheritableAttr {
- let Spellings = [GNU<"alloc_size">, CXX11<"gnu", "alloc_size">];
- let Args = [VariadicUnsignedArgument<"Args">];
-}
-
def AlwaysInline : InheritableAttr {
let Spellings = [GNU<"always_inline">, CXX11<"gnu", "always_inline">];
let Subjects = SubjectList<[Function]>;
}
}
-static void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
- if (!isFunctionOrMethod(D)) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << Attr.getName() << ExpectedFunctionOrMethod;
- return;
- }
-
- if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
- return;
-
- SmallVector<unsigned, 8> SizeArgs;
- for (unsigned i = 0; i < Attr.getNumArgs(); ++i) {
- Expr *Ex = Attr.getArgAsExpr(i);
- uint64_t Idx;
- if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(),
- Attr.getLoc(), i + 1, Ex, Idx))
- return;
-
- // check if the function argument is of an integer type
- QualType T = getFunctionOrMethodArgType(D, Idx).getNonReferenceType();
- if (!T->isIntegerType()) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
- << Attr.getName() << AANT_ArgumentIntegerConstant
- << Ex->getSourceRange();
- return;
- }
- SizeArgs.push_back(Idx);
- }
-
- // check if the function returns a pointer
- if (!getFunctionType(D)->getResultType()->isAnyPointerType()) {
- S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type)
- << Attr.getName() << 0 /*function*/<< 1 /*pointer*/ << D->getSourceRange();
- }
-
- D->addAttr(::new (S.Context)
- AllocSizeAttr(Attr.getRange(), S.Context,
- SizeArgs.data(), SizeArgs.size(),
- Attr.getAttributeSpellingListIndex()));
-}
-
static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// GCC ignores the nonnull attribute on K&R style function prototypes, so we
// ignore it as well
break;
case AttributeList::AT_Alias: handleAliasAttr (S, D, Attr); break;
case AttributeList::AT_Aligned: handleAlignedAttr (S, D, Attr); break;
- case AttributeList::AT_AllocSize: handleAllocSizeAttr (S, D, Attr); break;
case AttributeList::AT_AlwaysInline:
handleSimpleAttribute<AlwaysInlineAttr>(S, D, Attr); break;
case AttributeList::AT_AnalyzerNoReturn:
// CHECK: VarDecl{{.*}}TestType
// CHECK-NEXT: TypeTagForDatatypeAttr{{.*}} int
-void *TestVariadicUnsigned1(int) __attribute__((alloc_size(1)));
-// CHECK: FunctionDecl{{.*}}TestVariadicUnsigned1
-// CHECK: AllocSizeAttr{{.*}} 0
-
-void *TestVariadicUnsigned2(int, int) __attribute__((alloc_size(1,2)));
-// CHECK: FunctionDecl{{.*}}TestVariadicUnsigned2
-// CHECK: AllocSizeAttr{{.*}} 0 1
-
void TestLabel() {
L: __attribute__((unused)) int i;
// CHECK: LabelStmt{{.*}}'L'
+++ /dev/null
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-void* my_malloc(unsigned char) __attribute__((alloc_size(1)));
-void* my_calloc(unsigned char, short) __attribute__((alloc_size(1,2)));
-void* my_realloc(void*, unsigned) __attribute__((alloc_size(2)));
-
-
-void* fn1(int) __attribute__((alloc_size("xpto"))); // expected-error{{'alloc_size' attribute requires parameter 1 to be an integer constant}}
-
-void* fn2(void*) __attribute__((alloc_size(1))); // expected-error{{'alloc_size' attribute requires an integer constant}}
-
-void* fn3(unsigned) __attribute__((alloc_size(0))); // expected-error{{attribute parameter 1 is out of bounds}}
-void* fn4(unsigned) __attribute__((alloc_size(2))); // expected-error{{attribute parameter 1 is out of bounds}}
-
-void fn5(unsigned) __attribute__((alloc_size(1))); // expected-warning{{only applies to functions that return a pointer}}
-char fn6(unsigned) __attribute__((alloc_size(1))); // expected-warning{{only applies to functions that return a pointer}}
-
-void* fn7(unsigned) __attribute__((alloc_size)); // expected-error {{attribute takes at least 1 argument}}
-
-void *fn8(int, int) __attribute__((alloc_size(1, 1))); // OK
-
-void* fn9(unsigned) __attribute__((alloc_size(12345678901234567890123))); // expected-error {{integer constant is larger than the largest unsigned integer type}} // expected-error {{attribute parameter 1 is out of bounds}}
-
-void* fn10(size_t, size_t) __attribute__((alloc_size(1,2))); // expected-error{{redefinition of parameter}} \
- // expected-error{{a parameter list without types is only allowed in a function definition}} \
- // expected-error{{attribute parameter 1 is out of bounds}}
-void* fn11() __attribute__((alloc_size(1))); // expected-error{{attribute parameter 1 is out of bounds}}
void aligned_fn [[gnu::aligned(32)]] ();
struct [[gnu::aligned(8)]] aligned_struct {};
-[[gnu::malloc, gnu::alloc_size(1,2)]] void *alloc_size(int a, int b);
-
void always_inline [[gnu::always_inline]] ();
__thread int tls_model [[gnu::tls_model("local-exec")]];