Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -293,6 +293,9 @@ "static data member of %2|" "field of %2}1">, InGroup, DefaultIgnore; + +def error_inoutput_conflict_with_clobber : Error< + "asm-specifier for input or output variable conflicts with asm clobber list">; // C++ using declarations def err_using_requires_qualname : Error< Index: lib/CodeGen/CGStmt.cpp =================================================================== --- lib/CodeGen/CGStmt.cpp +++ lib/CodeGen/CGStmt.cpp @@ -1763,6 +1763,8 @@ std::string InOutConstraints; std::vector InOutArgs; std::vector InOutArgTypes; + std::vector > InputVars; + std::vector > OutputVars; // An inline asm can be marked readonly if it meets the following conditions: // - it doesn't have any sideeffects @@ -1781,6 +1783,7 @@ getTarget()); const Expr *OutExpr = S.getOutputExpr(i); + SourceLocation source = OutExpr->getLocStart(); OutExpr = OutExpr->IgnoreParenNoopCasts(getContext()); OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr, @@ -1859,6 +1862,7 @@ InOutArgTypes.push_back(Arg->getType()); InOutArgs.push_back(Arg); } + OutputVars.push_back(std::pair(OutputConstraint,source)); } // If this is a Microsoft-style asm blob, store the return registers (EAX:EDX) @@ -1877,6 +1881,7 @@ for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) { const Expr *InputExpr = S.getInputExpr(i); + SourceLocation source = InputExpr->getLocStart(); TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i]; @@ -1934,6 +1939,7 @@ ArgTypes.push_back(Arg->getType()); Args.push_back(Arg); Constraints += InputConstraint; + InputVars.push_back(std::pair(InputConstraint, source)); } // Append the "input" part of inout constraints last. @@ -1958,6 +1964,17 @@ Constraints += "~{"; Constraints += Clobber; Constraints += '}'; + std::string ClobberP = std::string("{"); + ClobberP += Clobber; + ClobberP += "}"; + for (std::vector >::iterator it = OutputVars.begin(); it != OutputVars.end(); ++it){ + if (ClobberP == it->first) + CGM.getDiags().Report(it->second, diag::error_inoutput_conflict_with_clobber); + } + for (std::vector >::iterator it = InputVars.begin(); it != InputVars.end(); ++it){ + if (ClobberP == it->first) + CGM.getDiags().Report(it->second, diag::error_inoutput_conflict_with_clobber); + } } // Add machine specific clobbers