Skip to content

Commit c46f8ef

Browse files
committed
[Clang] Support MSPropertyRefExpr as placement arg to new-expression
1 parent 8b2bdfb commit c46f8ef

File tree

5 files changed

+107
-8
lines changed

5 files changed

+107
-8
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,6 +2108,10 @@ class Sema final {
21082108

21092109
bool CheckFunctionReturnType(QualType T, SourceLocation Loc);
21102110

2111+
/// Check an argument list for placeholders that we won't try to
2112+
/// handle later.
2113+
bool CheckArgsForPlaceholders(MultiExprArg args);
2114+
21112115
/// Build a function type.
21122116
///
21132117
/// This routine checks the function type according to C++ rules and

clang/lib/Sema/SemaExpr.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5056,8 +5056,6 @@ static QualType getDependentArraySubscriptType(Expr *LHS, Expr *RHS,
50565056
return Result->isDependentType() ? Result : Ctx.DependentTy;
50575057
}
50585058

5059-
static bool checkArgsForPlaceholders(Sema &S, MultiExprArg args);
5060-
50615059
ExprResult Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base,
50625060
SourceLocation lbLoc,
50635061
MultiExprArg ArgExprs,
@@ -5161,7 +5159,7 @@ ExprResult Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base,
51615159
return ExprError();
51625160
ArgExprs[0] = result.get();
51635161
} else {
5164-
if (checkArgsForPlaceholders(*this, ArgExprs))
5162+
if (CheckArgsForPlaceholders(ArgExprs))
51655163
return ExprError();
51665164
}
51675165

@@ -6910,15 +6908,13 @@ static bool isPlaceholderToRemoveAsArg(QualType type) {
69106908
llvm_unreachable("bad builtin type kind");
69116909
}
69126910

6913-
/// Check an argument list for placeholders that we won't try to
6914-
/// handle later.
6915-
static bool checkArgsForPlaceholders(Sema &S, MultiExprArg args) {
6911+
bool Sema::CheckArgsForPlaceholders(MultiExprArg args) {
69166912
// Apply this processing to all the arguments at once instead of
69176913
// dying at the first failure.
69186914
bool hasInvalid = false;
69196915
for (size_t i = 0, e = args.size(); i != e; i++) {
69206916
if (isPlaceholderToRemoveAsArg(args[i]->getType())) {
6921-
ExprResult result = S.CheckPlaceholderExpr(args[i]);
6917+
ExprResult result = CheckPlaceholderExpr(args[i]);
69226918
if (result.isInvalid()) hasInvalid = true;
69236919
else args[i] = result.get();
69246920
}
@@ -7192,7 +7188,7 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
71927188
if (Result.isInvalid()) return ExprError();
71937189
Fn = Result.get();
71947190

7195-
if (checkArgsForPlaceholders(*this, ArgExprs))
7191+
if (CheckArgsForPlaceholders(ArgExprs))
71967192
return ExprError();
71977193

71987194
if (getLangOpts().CPlusPlus) {

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2286,6 +2286,9 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
22862286
bool PassAlignment = getLangOpts().AlignedAllocation &&
22872287
Alignment > NewAlignment;
22882288

2289+
if (CheckArgsForPlaceholders(PlacementArgs))
2290+
return ExprError();
2291+
22892292
AllocationFunctionScope Scope = UseGlobal ? AFS_Global : AFS_Both;
22902293
if (!AllocType->isDependentType() &&
22912294
!Expr::hasAnyTypeDependentArguments(PlacementArgs) &&
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// RUN: %clang_cc1 -emit-llvm -triple=x86_64-pc-win32 -fms-compatibility %s -o - | FileCheck %s
2+
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fms-compatibility -emit-pch -o %t %s
3+
// RUN: %clang_cc1 -emit-llvm -triple=x86_64-pc-win32 -fms-compatibility -include-pch %t -verify %s -o - | FileCheck %s
4+
// expected-no-diagnostics
5+
6+
#ifndef HEADER
7+
#define HEADER
8+
9+
struct S {
10+
int GetX() { return 42; }
11+
__declspec(property(get=GetX)) int x;
12+
13+
int GetY(int i, int j) { return i+j; }
14+
__declspec(property(get=GetY)) int y[];
15+
16+
void* operator new(__SIZE_TYPE__, int);
17+
};
18+
19+
template <typename T>
20+
struct TS {
21+
T GetT() { return T(); }
22+
__declspec(property(get=GetT)) T t;
23+
24+
T GetR(T i, T j) { return i+j; }
25+
__declspec(property(get=GetR)) T r[];
26+
};
27+
28+
// CHECK-LABEL: main
29+
int main(int argc, char **argv) {
30+
S *s;
31+
TS<double> *ts;
32+
33+
// CHECK: [[X:%.+]] = call noundef i32 @"?GetX@S@@QEAAHXZ"(ptr {{[^,]*}} %{{.+}})
34+
// CHECK-NEXT: call noundef ptr @"??2S@@SAPEAX_KH@Z"(i64 noundef 1, i32 noundef [[X]])
35+
new (s->x) S;
36+
37+
// CHECK: [[Y:%.+]] = call noundef i32 @"?GetY@S@@QEAAHHH@Z"(ptr {{[^,]*}} %{{.+}}, i32 noundef 1, i32 noundef 2)
38+
// CHECK-NEXT: call noundef ptr @"??2S@@SAPEAX_KH@Z"(i64 noundef 1, i32 noundef [[Y]])
39+
new ((s->y)[1][2]) S;
40+
41+
// CHECK: [[T:%.+]] = call noundef double @"?GetT@?$TS@N@@QEAANXZ"(ptr {{[^,]*}} %{{.+}})
42+
// CHECK-NEXT: [[TI:%.+]] = fptosi double [[T]] to i32
43+
// CHECK-NEXT: call noundef ptr @"??2S@@SAPEAX_KH@Z"(i64 noundef 1, i32 noundef [[TI]])
44+
new (ts->t) S;
45+
46+
// CHECK: [[R:%.+]] = call noundef double @"?GetR@?$TS@N@@QEAANNN@Z"(ptr {{[^,]*}} %{{.+}}, double {{[^,]*}}, double {{[^,]*}})
47+
// CHECK-NEXT: [[RI:%.+]] = fptosi double [[R]] to i32
48+
// CHECK-NEXT: call noundef ptr @"??2S@@SAPEAX_KH@Z"(i64 noundef 1, i32 noundef [[RI]])
49+
new ((ts->r)[1][2]) S;
50+
}
51+
52+
#endif
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: %clang_cc1 -ast-print -verify -triple=x86_64-pc-win32 -fms-compatibility %s -o - | FileCheck %s
2+
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fms-compatibility -emit-pch -o %t %s
3+
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fms-compatibility -include-pch %t -verify %s -ast-print -o - | FileCheck %s
4+
// expected-no-diagnostics
5+
6+
#ifndef HEADER
7+
#define HEADER
8+
9+
struct S {
10+
int GetX() { return 42; }
11+
__declspec(property(get=GetX)) int x;
12+
13+
int GetY(int i, int j) { return i+j; }
14+
__declspec(property(get=GetY)) int y[];
15+
16+
void* operator new(__SIZE_TYPE__, int);
17+
};
18+
19+
template <typename T>
20+
struct TS {
21+
T GetT() { return T(); }
22+
__declspec(property(get=GetT)) T t;
23+
24+
T GetR(T i, T j) { return i+j; }
25+
__declspec(property(get=GetR)) T r[];
26+
};
27+
28+
int main(int argc, char **argv) {
29+
// CHECK: S *s;
30+
// CHECK-NEXT: new (s->x) S;
31+
// CHECK-NEXT: new ((s->y)[1][2]) S;
32+
S *s;
33+
new (s->x) S;
34+
new ((s->y)[1][2]) S;
35+
36+
// CHECK-NEXT: TS<double> *ts;
37+
// CHECK-NEXT: new (ts->t) S;
38+
// CHECK-NEXT: new ((ts->r)[1][2]) S;
39+
TS<double> *ts;
40+
new (ts->t) S;
41+
new ((ts->r)[1][2]) S;
42+
}
43+
44+
#endif

0 commit comments

Comments
 (0)