forked from OSchip/llvm-project
Add support to fallback on operator new when a placement operator new[] is called for which there is no valid declaration. This fallback only happens in Microsoft compatibility mode. This patch addresses PR13164, and improves support for the WDK.
llvm-svn: 182905
This commit is contained in:
parent
543bdd1237
commit
324fbeeba7
|
@ -1554,13 +1554,28 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
|
|||
/*AllowMissing=*/true, OperatorNew))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!OperatorNew) {
|
||||
// Didn't find a member overload. Look for a global one.
|
||||
DeclareGlobalNewDelete();
|
||||
DeclContext *TUDecl = Context.getTranslationUnitDecl();
|
||||
bool FallbackEnabled = IsArray && Context.getLangOpts().MicrosoftMode;
|
||||
if (FindAllocationOverload(StartLoc, Range, NewName, AllocArgs, TUDecl,
|
||||
/*AllowMissing=*/FallbackEnabled, OperatorNew,
|
||||
/*Diagnose=*/!FallbackEnabled)) {
|
||||
if (!FallbackEnabled)
|
||||
return true;
|
||||
|
||||
// MSVC will fall back on trying to find a matching global operator new
|
||||
// if operator new[] cannot be found. Also, MSVC will leak by not
|
||||
// generating a call to operator delete or operator delete[], but we
|
||||
// will not replicate that bug.
|
||||
NewName = Context.DeclarationNames.getCXXOperatorName(OO_New);
|
||||
DeleteName = Context.DeclarationNames.getCXXOperatorName(OO_Delete);
|
||||
if (FindAllocationOverload(StartLoc, Range, NewName, AllocArgs, TUDecl,
|
||||
/*AllowMissing=*/false, OperatorNew))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// We don't need an operator delete if we're running under
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
// RUN: %clang_cc1 -triple i686-pc-win32 -fms-compatibility %s -emit-llvm -o - | FileCheck %s
|
||||
|
||||
struct arbitrary_t {} arbitrary;
|
||||
void *operator new(unsigned int size, arbitrary_t);
|
||||
|
||||
struct arbitrary2_t {} arbitrary2;
|
||||
void *operator new[](unsigned int size, arbitrary2_t);
|
||||
|
||||
namespace PR13164 {
|
||||
void f() {
|
||||
// MSVC will fall back on the non-array operator new.
|
||||
void *a;
|
||||
int *p = new(arbitrary) int[4];
|
||||
// CHECK: call i8* @_Znwj11arbitrary_t(i32 16, %struct.arbitrary_t*
|
||||
}
|
||||
|
||||
struct S {
|
||||
void *operator new[](unsigned int size, arbitrary_t);
|
||||
};
|
||||
|
||||
void g() {
|
||||
S *s = new(arbitrary) S[2];
|
||||
// CHECK: call i8* @_ZN7PR131641SnaEj11arbitrary_t(i32 2, %struct.arbitrary_t*
|
||||
S *s1 = new(arbitrary) S;
|
||||
// CHECK: call i8* @_Znwj11arbitrary_t(i32 1, %struct.arbitrary_t*
|
||||
}
|
||||
|
||||
struct T {
|
||||
void *operator new(unsigned int size, arbitrary2_t);
|
||||
};
|
||||
|
||||
void h() {
|
||||
// This should still call the global operator new[].
|
||||
T *t = new(arbitrary2) T[2];
|
||||
// CHECK: call i8* @_Znaj12arbitrary2_t(i32 2, %struct.arbitrary2_t*
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
struct arbitrary_t {} arbitrary;
|
||||
void *operator new(unsigned int size, arbitrary_t);
|
||||
|
||||
void f() {
|
||||
// Expect no error in MSVC compatibility mode
|
||||
int *p = new(arbitrary) int[4];
|
||||
}
|
Loading…
Reference in New Issue