forked from OSchip/llvm-project
implement support for __builtin_eh_return_data_regno on x86-32 and x86-64.
This implements PR5034 and rdar://6836445. llvm-svn: 82614
This commit is contained in:
parent
f47afd707e
commit
d545ad1301
|
@ -209,7 +209,6 @@
|
|||
DEB076CF0F3A222200F5A2BE /* DeclTemplate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEB076CE0F3A222200F5A2BE /* DeclTemplate.cpp */; };
|
||||
DEB077990F44F97800F5A2BE /* TokenConcatenation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEB077980F44F97800F5A2BE /* TokenConcatenation.cpp */; };
|
||||
DEB07AC80F4A427E00F5A2BE /* SemaAttr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEB07AC70F4A427E00F5A2BE /* SemaAttr.cpp */; };
|
||||
DEC63B1C0C7B940600DBF169 /* CFG.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEC63B1B0C7B940600DBF169 /* CFG.h */; };
|
||||
DEC8D9910A9433CD00353FCA /* Decl.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEC8D9900A9433CD00353FCA /* Decl.h */; };
|
||||
DEC8D9A40A94346E00353FCA /* AST.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEC8D9A30A94346E00353FCA /* AST.h */; };
|
||||
DECAB0D00DB3C84200E13CCB /* RewriteRope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECAB0CF0DB3C84200E13CCB /* RewriteRope.cpp */; };
|
||||
|
@ -327,7 +326,6 @@
|
|||
DE6951C70C4D1F5D00A5826B /* RecordLayout.h in CopyFiles */,
|
||||
DE6954640C5121BD00A5826B /* Token.h in CopyFiles */,
|
||||
DEF2E95F0C5FBD74000C4259 /* InternalsManual.html in CopyFiles */,
|
||||
DEC63B1C0C7B940600DBF169 /* CFG.h in CopyFiles */,
|
||||
DEF7D9F70C9C8B1A0001F598 /* Rewriter.h in CopyFiles */,
|
||||
84AF36A10CB17A3B00C820A5 /* DeclObjC.h in CopyFiles */,
|
||||
DE3986F00CB8D4B300223765 /* IdentifierTable.h in CopyFiles */,
|
||||
|
@ -679,7 +677,6 @@
|
|||
DEB077980F44F97800F5A2BE /* TokenConcatenation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TokenConcatenation.cpp; sourceTree = "<group>"; };
|
||||
DEB07AC70F4A427E00F5A2BE /* SemaAttr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaAttr.cpp; path = lib/Sema/SemaAttr.cpp; sourceTree = "<group>"; tabWidth = 2; };
|
||||
DEB089EE0F12F1D900522C07 /* TypeTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeTraits.h; sourceTree = "<group>"; };
|
||||
DEC63B1B0C7B940600DBF169 /* CFG.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CFG.h; path = clang/AST/CFG.h; sourceTree = "<group>"; tabWidth = 2; };
|
||||
DEC8D9900A9433CD00353FCA /* Decl.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Decl.h; path = clang/AST/Decl.h; sourceTree = "<group>"; tabWidth = 2; };
|
||||
DEC8D9A30A94346E00353FCA /* AST.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = AST.h; path = clang/AST/AST.h; sourceTree = "<group>"; tabWidth = 2; };
|
||||
DECAB0CF0DB3C84200E13CCB /* RewriteRope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RewriteRope.cpp; path = lib/Rewrite/RewriteRope.cpp; sourceTree = "<group>"; };
|
||||
|
@ -1303,7 +1300,6 @@
|
|||
90FB99DE0F98FB1D008F9415 /* DeclContextInternals.h */,
|
||||
90FB99DF0F98FB1D008F9415 /* DeclVisitor.h */,
|
||||
90FB99E00F98FB1D008F9415 /* ExternalASTSource.h */,
|
||||
DEC63B1B0C7B940600DBF169 /* CFG.h */,
|
||||
DEC8D9900A9433CD00353FCA /* Decl.h */,
|
||||
3538FDB60ED24A2C005EC283 /* DeclarationName.h */,
|
||||
035611470DA6A45C00D2EF2A /* DeclBase.h */,
|
||||
|
|
|
@ -247,6 +247,7 @@ BUILTIN(__builtin_flt_rounds, "i", "nc")
|
|||
BUILTIN(__builtin_setjmp, "iv**", "")
|
||||
BUILTIN(__builtin_longjmp, "vv**i", "")
|
||||
BUILTIN(__builtin_unwind_init, "v", "")
|
||||
BUILTIN(__builtin_eh_return_data_regno, "ii", "nc")
|
||||
|
||||
// GCC Object size checking builtins
|
||||
BUILTIN(__builtin_object_size, "zv*i", "n")
|
||||
|
|
|
@ -384,10 +384,17 @@ public:
|
|||
return RegParmMax;
|
||||
}
|
||||
|
||||
// isTLSSupported - Whether the target supports thread-local storage
|
||||
/// isTLSSupported - Whether the target supports thread-local storage.
|
||||
bool isTLSSupported() const {
|
||||
return TLSSupported;
|
||||
}
|
||||
|
||||
/// getEHDataRegisterNumber - Return the register number that
|
||||
/// __builtin_eh_return_regno would return with the specified argument.
|
||||
virtual int getEHDataRegisterNumber(unsigned RegNo) const {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
|
||||
|
|
|
@ -870,6 +870,12 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
|
|||
// __builtin_constant_p always has one operand: it returns true if that
|
||||
// operand can be folded, false otherwise.
|
||||
return Success(E->getArg(0)->isEvaluatable(Info.Ctx), E);
|
||||
|
||||
case Builtin::BI__builtin_eh_return_data_regno: {
|
||||
int Operand = E->getArg(0)->EvaluateAsInt(Info.Ctx).getZExtValue();
|
||||
Operand = Info.Ctx.Target.getEHDataRegisterNumber(Operand);
|
||||
return Success(Operand, E);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -900,6 +900,12 @@ public:
|
|||
virtual const char *getVAListDeclaration() const {
|
||||
return "typedef char* __builtin_va_list;";
|
||||
}
|
||||
|
||||
int getEHDataRegisterNumber(unsigned RegNo) const {
|
||||
if (RegNo == 0) return 0;
|
||||
if (RegNo == 1) return 2;
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
@ -990,6 +996,12 @@ public:
|
|||
"} __va_list_tag;"
|
||||
"typedef __va_list_tag __builtin_va_list[1];";
|
||||
}
|
||||
|
||||
int getEHDataRegisterNumber(unsigned RegNo) const {
|
||||
if (RegNo == 0) return 0;
|
||||
if (RegNo == 1) return 1;
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
|
|
@ -3700,6 +3700,7 @@ private:
|
|||
bool SemaBuiltinObjectSize(CallExpr *TheCall);
|
||||
bool SemaBuiltinLongjmp(CallExpr *TheCall);
|
||||
bool SemaBuiltinAtomicOverloaded(CallExpr *TheCall);
|
||||
bool SemaBuiltinEHReturnDataRegNo(CallExpr *TheCall);
|
||||
bool SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
|
||||
bool HasVAListArg, unsigned format_idx,
|
||||
unsigned firstDataArg);
|
||||
|
|
|
@ -138,6 +138,10 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
|
|||
if (SemaBuiltinStackAddress(TheCall))
|
||||
return ExprError();
|
||||
break;
|
||||
case Builtin::BI__builtin_eh_return_data_regno:
|
||||
if (SemaBuiltinEHReturnDataRegNo(TheCall))
|
||||
return ExprError();
|
||||
break;
|
||||
case Builtin::BI__builtin_shufflevector:
|
||||
return SemaBuiltinShuffleVector(TheCall);
|
||||
// TheCall will be freed by the smart pointer here, but that's fine, since
|
||||
|
@ -698,7 +702,7 @@ bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) {
|
|||
llvm::APSInt Result;
|
||||
if (!BT || BT->getKind() != BuiltinType::Int)
|
||||
return Diag(TheCall->getLocStart(), diag::err_prefetch_invalid_argument)
|
||||
<< SourceRange(Arg->getLocStart(), Arg->getLocEnd());
|
||||
<< Arg->getSourceRange();
|
||||
|
||||
if (Arg->isValueDependent())
|
||||
continue;
|
||||
|
@ -713,17 +717,29 @@ bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) {
|
|||
if (i == 1) {
|
||||
if (Result.getSExtValue() < 0 || Result.getSExtValue() > 1)
|
||||
return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range)
|
||||
<< "0" << "1" << SourceRange(Arg->getLocStart(), Arg->getLocEnd());
|
||||
<< "0" << "1" << Arg->getSourceRange();
|
||||
} else {
|
||||
if (Result.getSExtValue() < 0 || Result.getSExtValue() > 3)
|
||||
return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range)
|
||||
<< "0" << "3" << SourceRange(Arg->getLocStart(), Arg->getLocEnd());
|
||||
<< "0" << "3" << Arg->getSourceRange();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// SemaBuiltinEHReturnDataRegNo - Handle __builtin_eh_return_data_regno, the
|
||||
/// operand must be an integer constant.
|
||||
bool Sema::SemaBuiltinEHReturnDataRegNo(CallExpr *TheCall) {
|
||||
llvm::APSInt Result;
|
||||
if (!TheCall->getArg(0)->isIntegerConstantExpr(Result, Context))
|
||||
return Diag(TheCall->getLocStart(), diag::err_expr_not_ice)
|
||||
<< TheCall->getArg(0)->getSourceRange();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// SemaBuiltinObjectSize - Handle __builtin_object_size(void *ptr,
|
||||
/// int type). This simply type checks that type is one of the defined
|
||||
/// constants (0-3).
|
||||
|
|
|
@ -52,3 +52,13 @@ void test10(void) {
|
|||
|
||||
// No warning about falling off the end of a noreturn function.
|
||||
}
|
||||
|
||||
void test11(int X) {
|
||||
switch (X) {
|
||||
case __builtin_eh_return_data_regno(0): // constant foldable.
|
||||
break;
|
||||
}
|
||||
|
||||
__builtin_eh_return_data_regno(X); // expected-error {{not an integer constant expression}}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue