summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/APValue.cpp20
-rw-r--r--clang/lib/AST/ExprConstant.cpp11
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp11
-rw-r--r--clang/lib/Sema/SemaStmtAsm.cpp15
4 files changed, 46 insertions, 11 deletions
diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp
index e1876a933dc..f9cbf331b28 100644
--- a/clang/lib/AST/APValue.cpp
+++ b/clang/lib/AST/APValue.cpp
@@ -614,6 +614,26 @@ std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const {
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;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 1a21ad2539d..111cffe373e 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -9872,13 +9872,12 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
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);
}
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 5b5113b1e7e..b9905a2b3cc 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -1838,8 +1838,15 @@ llvm::Value* CodeGenFunction::EmitAsmInput(
// (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;
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 0d38f48aa5a..8c6012573c6 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -385,11 +385,20 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
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());
}
OpenPOWER on IntegriCloud