summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNuno Lopes <nunoplopes@sapo.pt>2009-12-16 16:59:22 +0000
committerNuno Lopes <nunoplopes@sapo.pt>2009-12-16 16:59:22 +0000
commit13c88c7269f7c2dac47d57534b51480e58e054e5 (patch)
tree549e13cd71b70b44e1ddb418d9ee60e41eb5b59d
parent59ae3c854240108b28a0b3cb0aa1e9fb4c90e5ff (diff)
downloadbcm5719-llvm-13c88c7269f7c2dac47d57534b51480e58e054e5.tar.gz
bcm5719-llvm-13c88c7269f7c2dac47d57534b51480e58e054e5.zip
implement PR5654: add -fassume-sane-operator-new, which is enabled by default, and adds the malloc attribute to the global function new() and to the overloaded new operators.
feel free to chage the name to this lengthy argument llvm-svn: 91543
-rw-r--r--clang/include/clang/Basic/LangOptions.h7
-rw-r--r--clang/include/clang/Driver/CC1Options.td2
-rw-r--r--clang/include/clang/Driver/Options.td2
-rw-r--r--clang/lib/Driver/Tools.cpp4
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp3
-rw-r--r--clang/lib/Sema/Sema.h3
-rw-r--r--clang/lib/Sema/SemaDecl.cpp5
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp12
-rw-r--r--clang/test/CodeGenCXX/new.cpp2
-rw-r--r--clang/test/CodeGenCXX/operator-new.cpp21
-rw-r--r--clang/test/CodeGenCXX/static-init.cpp2
11 files changed, 56 insertions, 7 deletions
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index e17279e2664..2b6092dea30 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -89,7 +89,10 @@ public:
unsigned ShortWChar : 1; // Force wchar_t to be unsigned short int.
unsigned OpenCL : 1; // OpenCL C99 language extensions.
-
+
+ unsigned AssumeSaneOperatorNew : 1; // Whether to add __attribute__((malloc))
+ // to the declaration of C++'s new
+ // operators
unsigned ElideConstructors : 1; // Whether C++ copy constructors should be
// elided if possible.
unsigned CatchUndefined :1; // Generate code to check for undefined ops.
@@ -141,6 +144,8 @@ public:
EmitAllDecls = 0;
MathErrno = 1;
+ AssumeSaneOperatorNew = 1;
+
// FIXME: The default should be 1.
AccessControl = 0;
ElideConstructors = 1;
diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td
index a9566f3f9d4..e830e473df8 100644
--- a/clang/include/clang/Driver/CC1Options.td
+++ b/clang/include/clang/Driver/CC1Options.td
@@ -304,6 +304,8 @@ def faltivec : Flag<"-faltivec">,
HelpText<"Enable AltiVec vector initializer syntax">;
def faccess_control : Flag<"-faccess-control">,
HelpText<"Enable C++ access control">;
+def fno_assume_sane_operator_new : Flag<"-fno-assume-sane-operator-new">,
+ HelpText<"Don't assume that C++'s new operator is sane">;
def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">,
HelpText<"Allow '$' in identifiers">;
def femit_all_decls : Flag<"-femit-all-decls">,
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 3592fc94684..7b0ce670259 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -226,6 +226,7 @@ def fPIC : Flag<"-fPIC">, Group<f_Group>;
def fPIE : Flag<"-fPIE">, Group<f_Group>;
def fapple_kext : Flag<"-fapple-kext">, Group<f_Group>;
def fasm_blocks : Flag<"-fasm-blocks">, Group<clang_ignored_f_Group>;
+def fassume_sane_operator_new : Flag<"-fassume-sane-operator-new">, Group<f_Group>;
def fastcp : Flag<"-fastcp">, Group<f_Group>;
def fastf : Flag<"-fastf">, Group<f_Group>;
def fast : Flag<"-fast">, Group<f_Group>;
@@ -277,6 +278,7 @@ def fmudflap : Flag<"-fmudflap">, Group<f_Group>;
def fnested_functions : Flag<"-fnested-functions">, Group<f_Group>;
def fnext_runtime : Flag<"-fnext-runtime">, Group<f_Group>;
def fno_asynchronous_unwind_tables : Flag<"-fno-asynchronous-unwind-tables">, Group<f_Group>;
+def fno_assume_sane_operator_new : Flag<"-fno-assume-sane-operator-new">, Group<f_Group>;
def fno_blocks : Flag<"-fno-blocks">, Group<f_Group>;
def fno_builtin_strcat : Flag<"-fno-builtin-strcat">, Group<f_Group>;
def fno_builtin_strcpy : Flag<"-fno-builtin-strcpy">, Group<f_Group>;
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 70597ab9139..8d823181279 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -945,6 +945,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin))
CmdArgs.push_back("-fno-builtin");
+ if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
+ options::OPT_fno_assume_sane_operator_new))
+ CmdArgs.push_back("-fno-assume-sane-operator-new");
+
// -fblocks=0 is default.
if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
getToolChain().IsBlocksDefault())) {
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 7a3388ffbb9..025f5ddf94d 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -466,6 +466,8 @@ static void LangOptsToArgs(const LangOptions &Opts,
Res.push_back("-ffreestanding");
if (Opts.NoBuiltin)
Res.push_back("-fno-builtin");
+ if (!Opts.AssumeSaneOperatorNew)
+ Res.push_back("-fno-assume-sane-operator-new");
if (Opts.ThreadsafeStatics)
llvm::llvm_report_error("FIXME: Not yet implemented!");
if (Opts.POSIXThreads)
@@ -1140,6 +1142,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
+ Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
Opts.AccessControl = Args.hasArg(OPT_faccess_control);
Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index 473f2c2820d..bca9ae9e5bc 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -1976,7 +1976,8 @@ public:
bool AllowMissing, FunctionDecl *&Operator);
void DeclareGlobalNewDelete();
void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return,
- QualType Argument);
+ QualType Argument,
+ bool addMallocAttr = false);
bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
DeclarationName Name, FunctionDecl* &Operator);
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 7a27e1185e3..bf5b350da0d 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2799,6 +2799,11 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
D.getIdentifierLoc(), Name, R, TInfo,
isStatic, isInline);
+ if ((Name.getCXXOverloadedOperator() == OO_New ||
+ Name.getCXXOverloadedOperator() == OO_Array_New) &&
+ getLangOptions().AssumeSaneOperatorNew)
+ NewFD->addAttr(::new (Context) MallocAttr());
+
isVirtualOkay = !isStatic;
} else {
// Determine whether the function was written with a
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 8870a59d136..9108137a000 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -715,13 +715,14 @@ void Sema::DeclareGlobalNewDelete() {
QualType VoidPtr = Context.getPointerType(Context.VoidTy);
QualType SizeT = Context.getSizeType();
+ bool AssumeSaneOperatorNew = getLangOptions().AssumeSaneOperatorNew;
DeclareGlobalAllocationFunction(
Context.DeclarationNames.getCXXOperatorName(OO_New),
- VoidPtr, SizeT);
+ VoidPtr, SizeT, AssumeSaneOperatorNew);
DeclareGlobalAllocationFunction(
Context.DeclarationNames.getCXXOperatorName(OO_Array_New),
- VoidPtr, SizeT);
+ VoidPtr, SizeT, AssumeSaneOperatorNew);
DeclareGlobalAllocationFunction(
Context.DeclarationNames.getCXXOperatorName(OO_Delete),
Context.VoidTy, VoidPtr);
@@ -733,7 +734,8 @@ void Sema::DeclareGlobalNewDelete() {
/// DeclareGlobalAllocationFunction - Declares a single implicit global
/// allocation function if it doesn't already exist.
void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
- QualType Return, QualType Argument) {
+ QualType Return, QualType Argument,
+ bool AddMallocAttr) {
DeclContext *GlobalCtx = Context.getTranslationUnitDecl();
// Check if this function is already declared.
@@ -766,6 +768,10 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
FunctionDecl::Create(Context, GlobalCtx, SourceLocation(), Name,
FnType, /*TInfo=*/0, FunctionDecl::None, false, true);
Alloc->setImplicit();
+
+ if (AddMallocAttr)
+ Alloc->addAttr(::new (Context) MallocAttr());
+
ParmVarDecl *Param = ParmVarDecl::Create(Context, Alloc, SourceLocation(),
0, Argument, /*TInfo=*/0,
VarDecl::None, 0);
diff --git a/clang/test/CodeGenCXX/new.cpp b/clang/test/CodeGenCXX/new.cpp
index f3c14a78d36..6ea12eb5f6b 100644
--- a/clang/test/CodeGenCXX/new.cpp
+++ b/clang/test/CodeGenCXX/new.cpp
@@ -92,7 +92,7 @@ A* t10() {
struct B { };
void t11() {
- // CHECK: call i8* @_Znwm
+ // CHECK: call noalias i8* @_Znwm
// CHECK: call void @llvm.memset.i64(
B* b = new B();
}
diff --git a/clang/test/CodeGenCXX/operator-new.cpp b/clang/test/CodeGenCXX/operator-new.cpp
new file mode 100644
index 00000000000..6becaae72cb
--- /dev/null
+++ b/clang/test/CodeGenCXX/operator-new.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -o %t-1.ll %s
+// RUN: FileCheck -check-prefix SANE --input-file=%t-1.ll %s
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -fno-assume-sane-operator-new -o %t-2.ll %s
+// RUN: FileCheck -check-prefix SANENOT --input-file=%t-2.ll %s
+
+
+class teste {
+ int A;
+ teste() : A(2) {}
+ void* operator new(unsigned) {return ::new teste();}
+};
+
+void f1() {
+ new teste();
+}
+
+// CHECK-SANE: define linkonce_odr noalias i8* @_ZN5testenwEj(
+// CHECK-SANE: declare noalias i8* @_Znwj(
+
+// CHECK-SANENOT: define linkonce_odr i8* @_ZN5testenwEj(
+// CHECK-SANENOT: declare i8* @_Znwj(
diff --git a/clang/test/CodeGenCXX/static-init.cpp b/clang/test/CodeGenCXX/static-init.cpp
index 2ad6e9411f4..cbd90e78940 100644
--- a/clang/test/CodeGenCXX/static-init.cpp
+++ b/clang/test/CodeGenCXX/static-init.cpp
@@ -11,7 +11,7 @@ void f() {
}
void g() {
- // CHECK: call i8* @_Znwm(i64 1)
+ // CHECK: call noalias i8* @_Znwm(i64 1)
// CHECK: call void @_ZN1AC1Ev(
static A& a = *new A;
}
OpenPOWER on IntegriCloud