]> granicus.if.org Git - clang/commitdiff
Avoid getting an argument of allocation function if it does not exist.
authorSerge Pavlov <sepavloff@gmail.com>
Sat, 14 Sep 2013 12:00:01 +0000 (12:00 +0000)
committerSerge Pavlov <sepavloff@gmail.com>
Sat, 14 Sep 2013 12:00:01 +0000 (12:00 +0000)
This is a fix to PR12778: in erroneous code an allocation function
can be declared with no arguments, quering the first argument in this case
causes assertion violation.

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

lib/Sema/SemaExprCXX.cpp
test/SemaCXX/PR12778.cpp [new file with mode: 0644]

index 9b703ed098868723a52326743feade035ccf5a64..f0417f724950adb44fa8126b536edc3e880786ca 100644 (file)
@@ -1948,22 +1948,23 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
   DeclContext *GlobalCtx = Context.getTranslationUnitDecl();
 
   // Check if this function is already declared.
-  {
-    DeclContext::lookup_result R = GlobalCtx->lookup(Name);
-    for (DeclContext::lookup_iterator Alloc = R.begin(), AllocEnd = R.end();
-         Alloc != AllocEnd; ++Alloc) {
-      // Only look at non-template functions, as it is the predefined,
-      // non-templated allocation function we are trying to declare here.
-      if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*Alloc)) {
+  DeclContext::lookup_result R = GlobalCtx->lookup(Name);
+  for (DeclContext::lookup_iterator Alloc = R.begin(), AllocEnd = R.end();
+       Alloc != AllocEnd; ++Alloc) {
+    // Only look at non-template functions, as it is the predefined,
+    // non-templated allocation function we are trying to declare here.
+    if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*Alloc)) {
+      if (Func->getNumParams() == 1) {
         QualType InitialParamType =
           Context.getCanonicalType(
             Func->getParamDecl(0)->getType().getUnqualifiedType());
         // FIXME: Do we need to check for default arguments here?
-        if (Func->getNumParams() == 1 && InitialParamType == Argument) {
+        if (InitialParamType == Argument) {
           if (AddMallocAttr && !Func->hasAttr<MallocAttr>())
-            Func->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
-          // Make the function visible to name lookup, even if we found it in an
-          // unimported module. It either is an implicitly-declared global
+            Func->addAttr(::new (Context) MallocAttr(SourceLocation(),
+                                                     Context));
+          // Make the function visible to name lookup, even if we found it in
+          // an unimported module. It either is an implicitly-declared global
           // allocation function, or is suppressing that function.
           Func->setHidden(false);
           return;
diff --git a/test/SemaCXX/PR12778.cpp b/test/SemaCXX/PR12778.cpp
new file mode 100644 (file)
index 0000000..f4d25f3
--- /dev/null
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void operator delete() throw(void*); // expected-error{{'operator delete' must have at least one parameter}}
+void* allocate(int __n) {
+   return ::operator new(__n);
+}
+