r224911 - Sema: Forbid inconsistent constraint alternatives

David Majnemer david.majnemer at gmail.com
Sun Dec 28 20:09:59 PST 2014


Author: majnemer
Date: Sun Dec 28 22:09:59 2014
New Revision: 224911

URL: http://llvm.org/viewvc/llvm-project?rev=224911&view=rev
Log:
Sema: Forbid inconsistent constraint alternatives

Verify that asm constraints have the same number of alternatives

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaStmtAsm.cpp
    cfe/trunk/test/Sema/asm.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=224911&r1=224910&r2=224911&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Dec 28 22:09:59 2014
@@ -6166,6 +6166,8 @@ let CategoryName = "Inline Assembly Issu
   def err_asm_tying_incompatible_types : Error<
     "unsupported inline asm: input with type "
     "%diff{$ matching output with type $|}0,1">;
+  def err_asm_unexpected_constraint_alternatives : Error<
+    "asm constraint has an unexpected number of alternatives: %0 vs %1">;
   def err_asm_incomplete_type : Error<"asm operand has incomplete type %0">;
   def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">;
   def err_asm_bad_register_type : Error<"bad type for named register variable">;

Modified: cfe/trunk/lib/Sema/SemaStmtAsm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAsm.cpp?rev=224911&r1=224910&r2=224911&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmtAsm.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmtAsm.cpp Sun Dec 28 22:09:59 2014
@@ -317,8 +317,28 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceL
   }
 
   // Validate tied input operands for type mismatches.
+  unsigned NumAlternatives = ~0U;
+  for (unsigned i = 0, e = OutputConstraintInfos.size(); i != e; ++i) {
+    TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i];
+    StringRef ConstraintStr = Info.getConstraintStr();
+    unsigned AltCount = ConstraintStr.count(',') + 1;
+    if (NumAlternatives == ~0U)
+      NumAlternatives = AltCount;
+    else if (NumAlternatives != AltCount)
+      return StmtError(Diag(NS->getOutputExpr(i)->getLocStart(),
+                            diag::err_asm_unexpected_constraint_alternatives)
+                       << NumAlternatives << AltCount);
+  }
   for (unsigned i = 0, e = InputConstraintInfos.size(); i != e; ++i) {
     TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
+    StringRef ConstraintStr = Info.getConstraintStr();
+    unsigned AltCount = ConstraintStr.count(',') + 1;
+    if (NumAlternatives == ~0U)
+      NumAlternatives = AltCount;
+    else if (NumAlternatives != AltCount)
+      return StmtError(Diag(NS->getInputExpr(i)->getLocStart(),
+                            diag::err_asm_unexpected_constraint_alternatives)
+                       << NumAlternatives << AltCount);
 
     // If this is a tied constraint, verify that the output and input have
     // either exactly the same type, or that they are int/ptr operands with the

Modified: cfe/trunk/test/Sema/asm.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/asm.c?rev=224911&r1=224910&r2=224911&view=diff
==============================================================================
--- cfe/trunk/test/Sema/asm.c (original)
+++ cfe/trunk/test/Sema/asm.c Sun Dec 28 22:09:59 2014
@@ -164,3 +164,10 @@ double f_output_constraint(void) {
   __asm("foo1": "=f" (result)); // expected-error {{invalid output constraint '=f' in asm}}
   return result;
 }
+
+void fn1() {
+  int l;
+  __asm__(""
+          : [l] "=r"(l)
+          : "[l],m"(l)); // expected-error {{asm constraint has an unexpected number of alternatives: 1 vs 2}}
+}





More information about the cfe-commits mailing list