[llvm-branch-commits] [cfe-branch] r355674 - Merging r355491:

Hans Wennborg via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Mar 8 01:16:31 PST 2019


Author: hans
Date: Fri Mar  8 01:16:31 2019
New Revision: 355674

URL: http://llvm.org/viewvc/llvm-project?rev=355674&view=rev
Log:
Merging r355491:
------------------------------------------------------------------------
r355491 | hans | 2019-03-06 11:26:19 +0100 (Wed, 06 Mar 2019) | 9 lines

Inline asm constraints: allow ICE-like pointers for the "n" constraint (PR40890)

Apparently GCC allows this, and there's code relying on it (see bug).

The idea is to allow expression that would have been allowed if they
were cast to int. So I based the code on how such a cast would be done
(the CK_PointerToIntegral case in IntExprEvaluator::VisitCastExpr()).

Differential Revision: https://reviews.llvm.org/D58821
------------------------------------------------------------------------

Modified:
    cfe/branches/release_80/   (props changed)
    cfe/branches/release_80/include/clang/AST/APValue.h
    cfe/branches/release_80/lib/AST/APValue.cpp
    cfe/branches/release_80/lib/AST/ExprConstant.cpp
    cfe/branches/release_80/lib/CodeGen/CGStmt.cpp
    cfe/branches/release_80/lib/Sema/SemaStmtAsm.cpp
    cfe/branches/release_80/test/CodeGen/x86-64-inline-asm.c
    cfe/branches/release_80/test/Sema/inline-asm-validate-x86.c

Propchange: cfe/branches/release_80/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Mar  8 01:16:31 2019
@@ -1,4 +1,4 @@
 /cfe/branches/type-system-rewrite:134693-134817
-/cfe/trunk:351334,351340,351344,351360,351457,351459,351531,351579-351580,352040,352079,352099,352102,352105,352156,352221-352222,352229,352307,352323,352463,352539,352610,352672,352822,353142,353393,353402,353411,353431,353493,353495,353656,353943,353976,354035,354074,354147,354351,354721,354723,354937,354968
+/cfe/trunk:351334,351340,351344,351360,351457,351459,351531,351579-351580,352040,352079,352099,352102,352105,352156,352221-352222,352229,352307,352323,352463,352539,352610,352672,352822,353142,353393,353402,353411,353431,353493,353495,353656,353943,353976,354035,354074,354147,354351,354721,354723,354937,354968,355491
 /cfe/trunk/test:170344
 /cfe/trunk/test/SemaTemplate:126920

Modified: cfe/branches/release_80/include/clang/AST/APValue.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_80/include/clang/AST/APValue.h?rev=355674&r1=355673&r2=355674&view=diff
==============================================================================
--- cfe/branches/release_80/include/clang/AST/APValue.h (original)
+++ cfe/branches/release_80/include/clang/AST/APValue.h Fri Mar  8 01:16:31 2019
@@ -257,6 +257,12 @@ public:
     return const_cast<APValue*>(this)->getInt();
   }
 
+  /// Try to convert this value to an integral constant. This works if it's an
+  /// integer, null pointer, or offset from a null pointer. Returns true on
+  /// success.
+  bool toIntegralConstant(APSInt &Result, QualType SrcTy,
+                          const ASTContext &Ctx) const;
+
   APFloat &getFloat() {
     assert(isFloat() && "Invalid accessor");
     return *(APFloat*)(char*)Data.buffer;

Modified: cfe/branches/release_80/lib/AST/APValue.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_80/lib/AST/APValue.cpp?rev=355674&r1=355673&r2=355674&view=diff
==============================================================================
--- cfe/branches/release_80/lib/AST/APValue.cpp (original)
+++ cfe/branches/release_80/lib/AST/APValue.cpp Fri Mar  8 01:16:31 2019
@@ -600,6 +600,26 @@ std::string APValue::getAsString(ASTCont
   return Result;
 }
 
+bool APValue::toIntegralConstant(APSInt &Result, QualType SrcTy,
+                                 const ASTContext &Ctx) const {
+  if (isInt()) {
+    Result = getInt();
+    return true;
+  }
+
+  if (isLValue() && isNullPointer()) {
+    Result = Ctx.MakeIntValue(Ctx.getTargetNullPointerValue(SrcTy), SrcTy);
+    return true;
+  }
+
+  if (isLValue() && !getLValueBase()) {
+    Result = Ctx.MakeIntValue(getLValueOffset().getQuantity(), SrcTy);
+    return true;
+  }
+
+  return false;
+}
+
 const APValue::LValueBase APValue::getLValueBase() const {
   assert(isLValue() && "Invalid accessor");
   return ((const LV*)(const void*)Data.buffer)->Base;

Modified: cfe/branches/release_80/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_80/lib/AST/ExprConstant.cpp?rev=355674&r1=355673&r2=355674&view=diff
==============================================================================
--- cfe/branches/release_80/lib/AST/ExprConstant.cpp (original)
+++ cfe/branches/release_80/lib/AST/ExprConstant.cpp Fri Mar  8 01:16:31 2019
@@ -9821,13 +9821,12 @@ bool IntExprEvaluator::VisitCastExpr(con
       return true;
     }
 
-    uint64_t V;
-    if (LV.isNullPointer())
-      V = Info.Ctx.getTargetNullPointerValue(SrcType);
-    else
-      V = LV.getLValueOffset().getQuantity();
+    APSInt AsInt;
+    APValue V;
+    LV.moveInto(V);
+    if (!V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
+      llvm_unreachable("Can't cast this!");
 
-    APSInt AsInt = Info.Ctx.MakeIntValue(V, SrcType);
     return Success(HandleIntToIntCast(Info, E, DestType, SrcType, AsInt), E);
   }
 

Modified: cfe/branches/release_80/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_80/lib/CodeGen/CGStmt.cpp?rev=355674&r1=355673&r2=355674&view=diff
==============================================================================
--- cfe/branches/release_80/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/branches/release_80/lib/CodeGen/CGStmt.cpp Fri Mar  8 01:16:31 2019
@@ -1821,8 +1821,15 @@ llvm::Value* CodeGenFunction::EmitAsmInp
   // (immediate or symbolic), try to emit it as such.
   if (!Info.allowsRegister() && !Info.allowsMemory()) {
     if (Info.requiresImmediateConstant()) {
-      llvm::APSInt AsmConst = InputExpr->EvaluateKnownConstInt(getContext());
-      return llvm::ConstantInt::get(getLLVMContext(), AsmConst);
+      Expr::EvalResult EVResult;
+      InputExpr->EvaluateAsRValue(EVResult, getContext(), true);
+
+      llvm::APSInt IntResult;
+      if (!EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(),
+                                           getContext()))
+        llvm_unreachable("Invalid immediate constant!");
+
+      return llvm::ConstantInt::get(getLLVMContext(), IntResult);
     }
 
     Expr::EvalResult Result;

Modified: cfe/branches/release_80/lib/Sema/SemaStmtAsm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_80/lib/Sema/SemaStmtAsm.cpp?rev=355674&r1=355673&r2=355674&view=diff
==============================================================================
--- cfe/branches/release_80/lib/Sema/SemaStmtAsm.cpp (original)
+++ cfe/branches/release_80/lib/Sema/SemaStmtAsm.cpp Fri Mar  8 01:16:31 2019
@@ -383,11 +383,20 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceL
           return StmtError(
               Diag(InputExpr->getBeginLoc(), diag::err_asm_immediate_expected)
               << Info.getConstraintStr() << InputExpr->getSourceRange());
-        llvm::APSInt Result = EVResult.Val.getInt();
-        if (!Info.isValidAsmImmediate(Result))
+
+        // For compatibility with GCC, we also allow pointers that would be
+        // integral constant expressions if they were cast to int.
+        llvm::APSInt IntResult;
+        if (!EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(),
+                                             Context))
+          return StmtError(
+              Diag(InputExpr->getBeginLoc(), diag::err_asm_immediate_expected)
+              << Info.getConstraintStr() << InputExpr->getSourceRange());
+
+        if (!Info.isValidAsmImmediate(IntResult))
           return StmtError(Diag(InputExpr->getBeginLoc(),
                                 diag::err_invalid_asm_value_for_constraint)
-                           << Result.toString(10) << Info.getConstraintStr()
+                           << IntResult.toString(10) << Info.getConstraintStr()
                            << InputExpr->getSourceRange());
       }
 

Modified: cfe/branches/release_80/test/CodeGen/x86-64-inline-asm.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_80/test/CodeGen/x86-64-inline-asm.c?rev=355674&r1=355673&r2=355674&view=diff
==============================================================================
--- cfe/branches/release_80/test/CodeGen/x86-64-inline-asm.c (original)
+++ cfe/branches/release_80/test/CodeGen/x86-64-inline-asm.c Fri Mar  8 01:16:31 2019
@@ -1,6 +1,7 @@
 // REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -triple x86_64 %s -S -o /dev/null -DWARN -verify
 // RUN: %clang_cc1 -triple x86_64 %s -S -o /dev/null -Werror -verify
+// RUN: %clang_cc1 -triple x86_64-linux-gnu %s -S -o - | FileCheck %s
 void f() {
   asm("movaps %xmm3, (%esi, 2)");
 // expected-note at 1 {{instantiated into assembly here}}
@@ -15,3 +16,17 @@ static unsigned var[1] = {};
 void g(void) { asm volatile("movd %%xmm0, %0"
                             :
                             : "m"(var)); }
+
+void pr40890(void) {
+  struct s {
+    int a, b;
+  } s;
+  __asm__ __volatile__("\n#define S_A abcd%0\n" : : "n"(&((struct s*)0)->a));
+  __asm__ __volatile__("\n#define S_B abcd%0\n" : : "n"(&((struct s*)0)->b));
+  __asm__ __volatile__("\n#define BEEF abcd%0\n" : : "n"((int*)0xdeadbeeeeeef));
+
+// CHECK-LABEL: pr40890
+// CHECK: #define S_A abcd$0
+// CHECK: #define S_B abcd$4
+// CHECK: #define BEEF abcd$244837814038255
+}

Modified: cfe/branches/release_80/test/Sema/inline-asm-validate-x86.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_80/test/Sema/inline-asm-validate-x86.c?rev=355674&r1=355673&r2=355674&view=diff
==============================================================================
--- cfe/branches/release_80/test/Sema/inline-asm-validate-x86.c (original)
+++ cfe/branches/release_80/test/Sema/inline-asm-validate-x86.c Fri Mar  8 01:16:31 2019
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -triple i686 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple x86_64 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64 -fsyntax-only -verify -DAMD64 %s
 
 void I(int i, int j) {
   static const int BelowMin = -1;
@@ -133,3 +133,21 @@ void O(int i, int j) {
           : "0"(i), "O"(64)); // expected-no-error
 }
 
+void pr40890(void) {
+  struct s {
+    int a, b;
+  };
+  static struct s s;
+  // This null pointer can be used as an integer constant expression.
+  __asm__ __volatile__("\n#define S_A abcd%0\n" : : "n"(&((struct s*)0)->a));
+  // This offset-from-null pointer can be used as an integer constant expression.
+  __asm__ __volatile__("\n#define S_B abcd%0\n" : : "n"(&((struct s*)0)->b));
+  // This pointer cannot be used as an integer constant expression.
+  __asm__ __volatile__("\n#define GLOBAL_A abcd%0\n" : : "n"(&s.a)); // expected-error{{constraint 'n' expects an integer constant expression}}
+  // Floating-point is also not okay.
+  __asm__ __volatile__("\n#define PI abcd%0\n" : : "n"(3.14f)); // expected-error{{constraint 'n' expects an integer constant expression}}
+#ifdef AMD64
+  // This arbitrary pointer is fine.
+  __asm__ __volatile__("\n#define BEEF abcd%0\n" : : "n"((int*)0xdeadbeeeeeef));
+#endif
+}




More information about the llvm-branch-commits mailing list