]> granicus.if.org Git - llvm/commitdiff
[C API] Prevent nullptr dereferences in C API for counting attributes.
authorAmaury Sechet <deadalnix@gmail.com>
Tue, 15 Nov 2016 22:19:59 +0000 (22:19 +0000)
committerAmaury Sechet <deadalnix@gmail.com>
Tue, 15 Nov 2016 22:19:59 +0000 (22:19 +0000)
See https://reviews.llvm.org/D26392

Patch by @maleadt

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

test/Bindings/llvm-c/callsite_attributes.ll [new file with mode: 0644]
test/Bindings/llvm-c/function_attributes.ll [new file with mode: 0644]
tools/llvm-c-test/CMakeLists.txt
tools/llvm-c-test/attributes.c [new file with mode: 0644]
tools/llvm-c-test/llvm-c-test.h
tools/llvm-c-test/main.c

diff --git a/test/Bindings/llvm-c/callsite_attributes.ll b/test/Bindings/llvm-c/callsite_attributes.ll
new file mode 100644 (file)
index 0000000..4b4e488
--- /dev/null
@@ -0,0 +1,12 @@
+; RUN: llvm-as %s -o %t.bc
+; RUN: llvm-c-test --test-callsite-attributes < %t.bc
+; This used to segfault
+
+define void @Y() {
+    ret void
+}
+
+define void @X() {
+    call void @X()
+    ret void
+}
diff --git a/test/Bindings/llvm-c/function_attributes.ll b/test/Bindings/llvm-c/function_attributes.ll
new file mode 100644 (file)
index 0000000..9aa1787
--- /dev/null
@@ -0,0 +1,7 @@
+; RUN: llvm-as %s -o %t.bc
+; RUN: llvm-c-test --test-function-attributes < %t.bc
+; This used to segfault
+
+define void @X() {
+    ret void
+}
index 858f2b07214a1bb22518ded45d04cc5ae8952564..a2bde0d9714f04e4e178381f8d9daf4454632f29 100644 (file)
@@ -36,6 +36,7 @@ if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
 endif ()
 
 add_llvm_tool(llvm-c-test
+  attributes.c
   calc.c
   diagnostic.c
   disassemble.c
diff --git a/tools/llvm-c-test/attributes.c b/tools/llvm-c-test/attributes.c
new file mode 100644 (file)
index 0000000..7f07a22
--- /dev/null
@@ -0,0 +1,75 @@
+/*===-- attributes.c - tool for testing libLLVM and llvm-c API ------------===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This file implements the --test-attributes and --test-callsite-attributes  *|
+|* commands in llvm-c-test.                                                   *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#include "llvm-c-test.h"
+
+#include <stdlib.h>
+
+int llvm_test_function_attributes(void) {
+  LLVMEnablePrettyStackTrace();
+
+  LLVMModuleRef M = llvm_load_module(false, true);
+
+  LLVMValueRef F = LLVMGetFirstFunction(M);
+  while (F) {
+    // Read attributes
+    for (int Idx = LLVMAttributeFunctionIndex, ParamCount = LLVMCountParams(F);
+         Idx <= ParamCount; ++Idx) {
+      int AttrCount = LLVMGetAttributeCountAtIndex(F, Idx);
+      LLVMAttributeRef *Attrs =
+          (LLVMAttributeRef *)malloc(AttrCount * sizeof(LLVMAttributeRef));
+      LLVMGetAttributesAtIndex(F, Idx, Attrs);
+      free(Attrs);
+    }
+    F = LLVMGetNextFunction(F);
+  }
+
+  LLVMDisposeModule(M);
+
+  return 0;
+}
+
+int llvm_test_callsite_attributes(void) {
+  LLVMEnablePrettyStackTrace();
+
+  LLVMModuleRef M = llvm_load_module(false, true);
+
+  LLVMValueRef F = LLVMGetFirstFunction(M);
+  while (F) {
+    LLVMBasicBlockRef BB;
+    for (BB = LLVMGetFirstBasicBlock(F); BB; BB = LLVMGetNextBasicBlock(BB)) {
+      LLVMValueRef I;
+      for (I = LLVMGetFirstInstruction(BB); I; I = LLVMGetNextInstruction(I)) {
+        if (LLVMIsACallInst(I)) {
+          // Read attributes
+          for (int Idx = LLVMAttributeFunctionIndex,
+                   ParamCount = LLVMCountParams(F);
+               Idx <= ParamCount; ++Idx) {
+            int AttrCount = LLVMGetCallSiteAttributeCount(I, Idx);
+            LLVMAttributeRef *Attrs = (LLVMAttributeRef *)malloc(
+                AttrCount * sizeof(LLVMAttributeRef));
+            LLVMGetCallSiteAttributes(I, Idx, Attrs);
+            free(Attrs);
+          }
+        }
+      }
+    }
+
+    F = LLVMGetNextFunction(F);
+  }
+
+  LLVMDisposeModule(M);
+
+  return 0;
+}
index 0d1ade093bc7f190d872546ed0adc71f05330e95..0401f1dbae386b86dca578c9d5cc7ab5be872d52 100644 (file)
@@ -52,6 +52,10 @@ int llvm_echo(void);
 // diagnostic.c
 int llvm_test_diagnostic_handler(void);
 
+// attributes.c
+int llvm_test_function_attributes();
+int llvm_test_callsite_attributes();
+
 #ifdef __cplusplus
 }
 #endif /* !defined(__cplusplus) */
index 90d3501778516b1f3182beb8b750ef912addb1d5..9bc0c96c3d6519b41e31db4a2baf8dc414ae3765 100644 (file)
@@ -88,6 +88,10 @@ int main(int argc, char **argv) {
     return llvm_add_named_metadata_operand();
   } else if (argc == 2 && !strcmp(argv[1], "--set-metadata")) {
     return llvm_set_metadata();
+  } else if (argc == 2 && !strcmp(argv[1], "--test-function-attributes")) {
+    return llvm_test_function_attributes();
+  } else if (argc == 2 && !strcmp(argv[1], "--test-callsite-attributes")) {
+    return llvm_test_callsite_attributes();
   } else if (argc == 2 && !strcmp(argv[1], "--echo")) {
     return llvm_echo();
   } else if (argc == 2 && !strcmp(argv[1], "--test-diagnostic-handler")) {