зеркало из https://github.com/microsoft/clang.git
fix rdar://6097892 - gcc incompat: clang rejects __func__, __FUNCTION__, and __PRETTY_FUNCTION__ outside func
Yeah, this is "useful". git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60921 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
cd08707a96
Коммит
b0da923653
|
@ -676,7 +676,7 @@ DIAG(warn_octal_escape_too_large, WARNING,
|
|||
DIAG(err_hex_escape_no_digits, ERROR,
|
||||
"\\x used with no following hex digits")
|
||||
|
||||
DIAG(err_predef_outside_function, ERROR,
|
||||
DIAG(ext_predef_outside_function, WARNING,
|
||||
"predefined identifier is only valid inside function")
|
||||
|
||||
// Declarations.
|
||||
|
|
|
@ -597,17 +597,19 @@ Sema::ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
|
|||
case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break;
|
||||
}
|
||||
|
||||
// Verify that this is in a function context.
|
||||
if (getCurFunctionOrMethodDecl() == 0)
|
||||
return Diag(Loc, diag::err_predef_outside_function);
|
||||
|
||||
// Pre-defined identifiers are of type char[x], where x is the length of the
|
||||
// string.
|
||||
unsigned Length;
|
||||
if (FunctionDecl *FD = getCurFunctionDecl())
|
||||
Length = FD->getIdentifier()->getLength();
|
||||
else
|
||||
Length = getCurMethodDecl()->getSynthesizedMethodSize();
|
||||
else if (ObjCMethodDecl *MD = getCurMethodDecl())
|
||||
Length = MD->getSynthesizedMethodSize();
|
||||
else {
|
||||
Diag(Loc, diag::ext_predef_outside_function);
|
||||
// __PRETTY_FUNCTION__ -> "top level", the others produce an empty string.
|
||||
Length = IT == PredefinedExpr::PrettyFunction ? strlen("top level") : 0;
|
||||
}
|
||||
|
||||
|
||||
llvm::APInt LengthI(32, Length + 1);
|
||||
QualType ResTy = Context.CharTy.getQualifiedType(QualType::Const);
|
||||
|
|
|
@ -5,8 +5,15 @@ void abcdefghi12(void) {
|
|||
static int arr[sizeof(__func__)==12 ? 1 : -1];
|
||||
}
|
||||
|
||||
char *X = __func__; // expected-error {{predefined identifier is only valid}}
|
||||
char *X = __func__; // expected-warning {{predefined identifier is only valid}} \
|
||||
expected-warning {{initializing 'char const [1]' discards qualifiers, expected 'char *'}}
|
||||
|
||||
void a() {
|
||||
__func__[0] = 'a'; // expected-error {{variable is not assignable}}
|
||||
}
|
||||
|
||||
// rdar://6097892 - GCC permits this insanity.
|
||||
const char *b = __func__; // expected-warning {{predefined identifier is only valid}}
|
||||
const char *c = __FUNCTION__; // expected-warning {{predefined identifier is only valid}}
|
||||
const char *d = __PRETTY_FUNCTION__; // expected-warning {{predefined identifier is only valid}}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче