[AsmParser] Check forward reference type with opaque pointers
authorNikita Popov <npopov@redhat.com>
Fri, 11 Mar 2022 16:14:48 +0000 (17:14 +0100)
committerNikita Popov <npopov@redhat.com>
Fri, 11 Mar 2022 16:16:34 +0000 (17:16 +0100)
While we don't need to check the element type in this case, we
do need to make sure that the pointers have the same address space,
otherwise RAUW will assert.

llvm/lib/AsmParser/LLParser.cpp
llvm/test/Assembler/opaque-ptr-invalid-forward-ref-2.ll [new file with mode: 0644]
llvm/test/Assembler/opaque-ptr-invalid-forward-ref.ll [new file with mode: 0644]

index adeb3ba..a98c528 100644 (file)
@@ -1168,7 +1168,7 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc,
   GV->setUnnamedAddr(UnnamedAddr);
 
   if (GVal) {
-    if (!GVal->getType()->isOpaque() && GVal->getValueType() != Ty)
+    if (GVal->getType() != Ty->getPointerTo(AddrSpace))
       return error(
           TyLoc,
           "forward reference and definition of global have different types");
@@ -5626,20 +5626,19 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
     auto FRVI = ForwardRefVals.find(FunctionName);
     if (FRVI != ForwardRefVals.end()) {
       FwdFn = FRVI->second.first;
-      if (!FwdFn->getType()->isOpaque()) {
-        if (!FwdFn->getType()->getNonOpaquePointerElementType()->isFunctionTy())
-          return error(FRVI->second.second, "invalid forward reference to "
-                                            "function as global value!");
-        if (FwdFn->getType() != PFT)
-          return error(FRVI->second.second,
-                       "invalid forward reference to "
-                       "function '" +
-                           FunctionName +
-                           "' with wrong type: "
-                           "expected '" +
-                           getTypeString(PFT) + "' but was '" +
-                           getTypeString(FwdFn->getType()) + "'");
-      }
+      if (!FwdFn->getType()->isOpaque() &&
+          !FwdFn->getType()->getNonOpaquePointerElementType()->isFunctionTy())
+        return error(FRVI->second.second, "invalid forward reference to "
+                                          "function as global value!");
+      if (FwdFn->getType() != PFT)
+        return error(FRVI->second.second,
+                     "invalid forward reference to "
+                     "function '" +
+                         FunctionName +
+                         "' with wrong type: "
+                         "expected '" +
+                         getTypeString(PFT) + "' but was '" +
+                         getTypeString(FwdFn->getType()) + "'");
       ForwardRefVals.erase(FRVI);
     } else if ((Fn = M->getFunction(FunctionName))) {
       // Reject redefinitions.
@@ -5655,7 +5654,7 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
     auto I = ForwardRefValIDs.find(NumberedVals.size());
     if (I != ForwardRefValIDs.end()) {
       FwdFn = I->second.first;
-      if (!FwdFn->getType()->isOpaque() && FwdFn->getType() != PFT)
+      if (FwdFn->getType() != PFT)
         return error(NameLoc, "type of definition and forward reference of '@" +
                                   Twine(NumberedVals.size()) +
                                   "' disagree: "
diff --git a/llvm/test/Assembler/opaque-ptr-invalid-forward-ref-2.ll b/llvm/test/Assembler/opaque-ptr-invalid-forward-ref-2.ll
new file mode 100644 (file)
index 0000000..bda9ee8
--- /dev/null
@@ -0,0 +1,6 @@
+; RUN: not llvm-as -opaque-pointers < %s 2>&1 | FileCheck %s
+
+; CHECK: forward reference and definition of global have different types
+
+@a = alias i32, ptr addrspace(1) @g
+@g = global i32 0
diff --git a/llvm/test/Assembler/opaque-ptr-invalid-forward-ref.ll b/llvm/test/Assembler/opaque-ptr-invalid-forward-ref.ll
new file mode 100644 (file)
index 0000000..9e11e78
--- /dev/null
@@ -0,0 +1,9 @@
+; RUN: not llvm-as -opaque-pointers < %s 2>&1 | FileCheck %s
+
+; CHECK: invalid forward reference to function 'f' with wrong type: expected 'ptr' but was 'ptr addrspace(1)'
+
+@a = alias void (), ptr addrspace(1) @f
+
+define void @f() {
+  ret void
+}