]> granicus.if.org Git - clang/commitdiff
Split out logic for valid clobbers and valid inline asm registers.
authorEric Christopher <echristo@apple.com>
Tue, 28 Jun 2011 18:20:53 +0000 (18:20 +0000)
committerEric Christopher <echristo@apple.com>
Tue, 28 Jun 2011 18:20:53 +0000 (18:20 +0000)
Fixes rdar://9281377

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

include/clang/Basic/TargetInfo.h
lib/Basic/TargetInfo.cpp
lib/CodeGen/CGStmt.cpp
lib/Sema/SemaStmt.cpp
test/Sema/asm.c

index a1625bfc9e868eb3a69b75f1aea981b93c84f264..4559cf2f64bed1fe3ede6a394477b05e93b38b44 100644 (file)
@@ -303,6 +303,11 @@ public:
   /// __builtin_va_list, which is target-specific.
   virtual const char *getVAListDeclaration() const = 0;
 
+  /// isValidClobber - Returns whether the passed in string is
+  /// a valid clobber in an inline asm statement. This is used by
+  /// Sema.
+  bool isValidClobber(llvm::StringRef Name) const;
+
   /// isValidGCCRegisterName - Returns whether the passed in string
   /// is a valid register name according to GCC. This is used by Sema for
   /// inline asm statements.
index 2d4c4a97916c711b6e54322876a21fc5e4067478..30a9bdb3177487d269766497200c846a9abca30a 100644 (file)
@@ -181,6 +181,14 @@ static llvm::StringRef removeGCCRegisterPrefix(llvm::StringRef Name) {
   return Name;
 }
 
+/// isValidClobber - Returns whether the passed in string is
+/// a valid clobber in an inline asm statement. This is used by
+/// Sema.
+bool TargetInfo::isValidClobber(llvm::StringRef Name) const {
+  return (isValidGCCRegisterName(Name) ||
+         Name == "memory" || Name == "cc");
+}
+
 /// isValidGCCRegisterName - Returns whether the passed in string
 /// is a valid register name according to GCC. This is used by Sema for
 /// inline asm statements.
@@ -194,9 +202,6 @@ bool TargetInfo::isValidGCCRegisterName(llvm::StringRef Name) const {
   // Get rid of any register prefix.
   Name = removeGCCRegisterPrefix(Name);
 
-  if (Name == "memory" || Name == "cc")
-    return true;
-
   getGCCRegNames(Names, NumNames);
 
   // If we have a number it maps to an entry in the register name array.
index f5bd56efb25081b78d7ea8ebdcf82dcaa952c081..5d5ab2f97aad96d563a7920c38b3cbdccf57bf37 100644 (file)
@@ -1558,6 +1558,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
   for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) {
     llvm::StringRef Clobber = S.getClobber(i)->getString();
 
+    if (Clobber != "memory" && Clobber != "cc")
     Clobber = Target.getNormalizedGCCRegisterName(Clobber);
 
     if (i != 0 || NumConstraints != 0)
index 0ba4f99abce565de7a49114e7d549b439002358b..75124c19084b67d9465cc68a89b64587e9cc26cf 100644 (file)
@@ -1990,7 +1990,7 @@ StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, bool IsSimple,
 
     llvm::StringRef Clobber = Literal->getString();
 
-    if (!Context.Target.isValidGCCRegisterName(Clobber))
+    if (!Context.Target.isValidClobber(Clobber))
       return StmtError(Diag(Literal->getLocStart(),
                   diag::err_asm_unknown_register_name) << Clobber);
   }
@@ -2350,4 +2350,3 @@ Sema::ActOnSEHFinallyBlock(SourceLocation Loc,
   assert(Block);
   return Owned(SEHFinallyStmt::Create(Context,Loc,Block));
 }
-
index d8161c819b99078a5323406ee008b194fb997e1d..a3313cad2b4b42a36a710825b8cc4785e923a675 100644 (file)
@@ -113,3 +113,7 @@ void test11(void) {
   _Bool b;
   asm volatile ("movb %%gs:%P2,%b0" : "=q"(b) : "0"(0), "i"(5L));
 }
+
+void test12(void) {
+  register int cc __asm ("cc"); // expected-error{{unknown register name 'cc' in asm}}
+}