]> granicus.if.org Git - clang/commitdiff
When diagnosing the arguments to alloc_size, report the failing argument using a...
authorAaron Ballman <aaron@aaronballman.com>
Sun, 25 Feb 2018 20:40:06 +0000 (20:40 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Sun, 25 Feb 2018 20:40:06 +0000 (20:40 +0000)
Patch by Joel Denny.

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

lib/Sema/SemaDeclAttr.cpp
test/Sema/alloc-size.c

index dea16f9f7c7cde7d58db48c446c196c4d52420ae..b5614cc7081d11b24ea2a003e9cc90c2d2c0effa 100644 (file)
@@ -765,19 +765,19 @@ static void handleAssertExclusiveLockAttr(Sema &S, Decl *D,
       AL.getAttributeSpellingListIndex()));
 }
 
-/// \brief Checks to be sure that the given parameter number is in bounds, and is
-/// an integral type. Will emit appropriate diagnostics if this returns
+/// \brief Checks to be sure that the given parameter number is in bounds, and
+/// is an integral type. Will emit appropriate diagnostics if this returns
 /// false.
 ///
-/// FuncParamNo is expected to be from the user, so is base-1. AttrArgNo is used
-/// to actually retrieve the argument, so it's base-0.
+/// AttrArgNo is used to actually retrieve the argument, so it's base-0.
 template <typename AttrInfo>
 static bool checkParamIsIntegerType(Sema &S, const FunctionDecl *FD,
-                                    const AttrInfo &AI, Expr *AttrArg,
-                                    unsigned FuncParamNo, unsigned AttrArgNo,
+                                    const AttrInfo &AI, unsigned AttrArgNo,
                                     bool AllowDependentType = false) {
+  assert(AI.isArgExpr(AttrArgNo) && "Expected expression argument");
+  Expr *AttrArg = AI.getArgAsExpr(AttrArgNo);
   uint64_t Idx;
-  if (!checkFunctionOrMethodParameterIndex(S, FD, AI, FuncParamNo, AttrArg,
+  if (!checkFunctionOrMethodParameterIndex(S, FD, AI, AttrArgNo + 1, AttrArg,
                                            Idx))
     return false;
 
@@ -793,20 +793,6 @@ static bool checkParamIsIntegerType(Sema &S, const FunctionDecl *FD,
   return true;
 }
 
-/// \brief Checks to be sure that the given parameter number is in bounds, and is
-/// an integral type. Will emit appropriate diagnostics if this returns false.
-///
-/// FuncParamNo is expected to be from the user, so is base-1. AttrArgNo is used
-/// to actually retrieve the argument, so it's base-0.
-static bool checkParamIsIntegerType(Sema &S, const FunctionDecl *FD,
-                                    const AttributeList &AL,
-                                    unsigned FuncParamNo, unsigned AttrArgNo,
-                                    bool AllowDependentType = false) {
-  assert(AL.isArgExpr(AttrArgNo) && "Expected expression argument");
-  return checkParamIsIntegerType(S, FD, AL, AL.getArgAsExpr(AttrArgNo),
-                                 FuncParamNo, AttrArgNo, AllowDependentType);
-}
-
 static void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &AL) {
   if (!checkAttributeAtLeastNumArgs(S, AL, 1) ||
       !checkAttributeAtMostNumArgs(S, AL, 2))
@@ -825,7 +811,7 @@ static void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &AL) {
   if (!checkPositiveIntArgument(S, AL, SizeExpr, SizeArgNo, /*Index=*/1))
     return;
 
-  if (!checkParamIsIntegerType(S, FD, AL, SizeArgNo, /*AttrArgNo=*/0))
+  if (!checkParamIsIntegerType(S, FD, AL, /*AttrArgNo=*/0))
     return;
 
   // Args are 1-indexed, so 0 implies that the arg was not present
@@ -837,7 +823,7 @@ static void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &AL) {
                                   /*Index=*/2))
       return;
 
-    if (!checkParamIsIntegerType(S, FD, AL, NumberArgNo, /*AttrArgNo=*/1))
+    if (!checkParamIsIntegerType(S, FD, AL, /*AttrArgNo=*/1))
       return;
   }
 
index 7004a5a7d7f6fa3d6364e2db4be60de0c573376d..56181511a1948fe0a0c594591d458d35c38b6bf1 100644 (file)
@@ -3,14 +3,14 @@
 void *fail1(int a) __attribute__((alloc_size)); //expected-error{{'alloc_size' attribute takes at least 1 argument}}
 void *fail2(int a) __attribute__((alloc_size())); //expected-error{{'alloc_size' attribute takes at least 1 argument}}
 
-void *fail3(int a) __attribute__((alloc_size(0))); //expected-error{{'alloc_size' attribute parameter 0 is out of bounds}}
-void *fail4(int a) __attribute__((alloc_size(2))); //expected-error{{'alloc_size' attribute parameter 2 is out of bounds}}
+void *fail3(int a) __attribute__((alloc_size(0))); //expected-error{{'alloc_size' attribute parameter 1 is out of bounds}}
+void *fail4(int a) __attribute__((alloc_size(2))); //expected-error{{'alloc_size' attribute parameter 1 is out of bounds}}
 
-void *fail5(int a, int b) __attribute__((alloc_size(0, 1))); //expected-error{{'alloc_size' attribute parameter 0 is out of bounds}}
-void *fail6(int a, int b) __attribute__((alloc_size(3, 1))); //expected-error{{'alloc_size' attribute parameter 3 is out of bounds}}
+void *fail5(int a, int b) __attribute__((alloc_size(0, 1))); //expected-error{{'alloc_size' attribute parameter 1 is out of bounds}}
+void *fail6(int a, int b) __attribute__((alloc_size(3, 1))); //expected-error{{'alloc_size' attribute parameter 1 is out of bounds}}
 
-void *fail7(int a, int b) __attribute__((alloc_size(1, 0))); //expected-error{{'alloc_size' attribute parameter 0 is out of bounds}}
-void *fail8(int a, int b) __attribute__((alloc_size(1, 3))); //expected-error{{'alloc_size' attribute parameter 3 is out of bounds}}
+void *fail7(int a, int b) __attribute__((alloc_size(1, 0))); //expected-error{{'alloc_size' attribute parameter 2 is out of bounds}}
+void *fail8(int a, int b) __attribute__((alloc_size(1, 3))); //expected-error{{'alloc_size' attribute parameter 2 is out of bounds}}
 
 int fail9(int a) __attribute__((alloc_size(1))); //expected-warning{{'alloc_size' attribute only applies to return values that are pointers}}