Skip to content

Commit 984a814

Browse files
Stop mkString from producing the extra space in int * x[10].
The problem already affected several regression tests for more complex cases (which expected the extra space), and we didn't seem to notice or care. But now it is affecting every unchanged variable of that form in a multi-decl that gets rewritten, and this broke several other regression tests.
1 parent 4263f16 commit 984a814

File tree

6 files changed

+44
-15
lines changed

6 files changed

+44
-15
lines changed

clang/lib/3C/ConstraintVariables.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -834,10 +834,31 @@ PointerVariableConstraint::mkString(Constraints &CS,
834834
if (!ForItype && InferredGenericIndex == -1 && isVoidPtr())
835835
K = Atom::A_Wild;
836836

837+
// In a case like `_Ptr<T> g[1]`, we need to push the ` g` onto EndStrs
838+
// before we can push the `>` and start drilling into T.
839+
//
840+
// Exception: In a case like `int *g[1]`, we don't want an extra space after
841+
// the `*` but we don't yet know whether we have a `*`, so we skip emitting
842+
// the name. We have to also skip the addArrayAnnotations because it would
843+
// cause the array annotations to be emitted before the name.
844+
//
845+
// Exception to the exception: In a case like `void (*fs[2])()`, we still
846+
// want to avoid emitting the name (which would add an extra space after the
847+
// `*`), but we _do_ need to call addArrayAnnotations so the array
848+
// annotations end up with the variable name rather than after the function
849+
// parameter list. The function pointer code knows to emit the name before
850+
// EndStrs.
851+
//
852+
// This passes the current regression tests but feels very ad-hoc.
853+
// REVIEW: Help me redesign this code!
837854
if (PrevArr && ArrSizes.at(TypeIdx).first != O_SizedArray && !EmittedName) {
838-
EmittedName = true;
839-
addArrayAnnotations(ConstArrs, EndStrs);
840-
EndStrs.push_front(" " + UseName);
855+
if (K != Atom::A_Wild || FV != nullptr) {
856+
addArrayAnnotations(ConstArrs, EndStrs);
857+
}
858+
if (K != Atom::A_Wild) {
859+
EmittedName = true;
860+
EndStrs.push_front(" " + UseName);
861+
}
841862
}
842863
PrevArr = ArrSizes.at(TypeIdx).first == O_SizedArray;
843864

@@ -927,6 +948,8 @@ PointerVariableConstraint::mkString(Constraints &CS,
927948
// the the stack array type.
928949
if (PrevArr && !EmittedName && AllArrays) {
929950
EmittedName = true;
951+
// Note: If the whole type is an array, we can't have a "*", so we don't
952+
// need to worry about an extra space.
930953
EndStrs.push_front(" " + UseName);
931954
}
932955

@@ -965,8 +988,14 @@ PointerVariableConstraint::mkString(Constraints &CS,
965988
}
966989

967990
// No space after itype.
968-
if (!EmittedName && !UseName.empty())
969-
Ss << " " << UseName;
991+
if (!EmittedName && !UseName.empty()) {
992+
// REVIEW: Is there a better way? This might actually be less of a
993+
// maintenance problem than trying to have all code paths correctly set an
994+
// explicit flag for whether to add a space.
995+
if (!StringRef(Ss.str()).endswith("*"))
996+
Ss << " ";
997+
Ss << UseName;
998+
}
970999

9711000
// Final array dropping.
9721001
if (!ConstArrs.empty()) {

clang/test/3C/compound_literal.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ void lists() {
6767

6868
int *d[2] = (int *[2]){&x, (int *)1};
6969
//CHECK_NOALL: int *d[2] = (int *[2]){&x, (int *)1};
70-
//CHECK_ALL: int * d _Checked[2] = (int * _Checked[2]){&x, (int *)1};
70+
//CHECK_ALL: int *d _Checked[2] = (int * _Checked[2]){&x, (int *)1};
7171
int *d0 = d[0];
7272
//CHECK: int *d0 = d[0];
7373

clang/test/3C/fptr_array.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@
99

1010
void (*fs[2])(int *);
1111
void (*f)(int *);
12-
//CHECK_NOALL: void (* fs[2])(_Ptr<int>) = {((void *)0)};
12+
//CHECK_NOALL: void (*fs[2])(_Ptr<int>) = {((void *)0)};
1313
//CHECK_NOALL: void (*f)(_Ptr<int>) = ((void *)0);
1414
//CHECK_ALL: _Ptr<void (_Ptr<int>)> fs _Checked[2] = {((void *)0)};
1515
//CHECK_ALL: _Ptr<void (_Ptr<int>)> f = ((void *)0);
1616

1717
void (*gs[2])(int *);
1818
void g_impl(int *x) { x = 1; }
1919
void (*g)(int *) = g_impl;
20-
//CHECK_NOALL: void (* gs[2])(int * : itype(_Ptr<int>)) = {((void *)0)};
20+
//CHECK_NOALL: void (*gs[2])(int * : itype(_Ptr<int>)) = {((void *)0)};
2121
//CHECK_NOALL: void g_impl(int *x : itype(_Ptr<int>)) { x = 1; }
2222
//CHECK_NOALL: void (*g)(int * : itype(_Ptr<int>)) = g_impl;
2323

@@ -30,21 +30,21 @@ void (*h)(void *);
3030

3131
int *(*is[2])(void);
3232
int *(*i)(void);
33-
//CHECK_NOALL: _Ptr<int> (* is[2])(void) = {((void *)0)};
33+
//CHECK_NOALL: _Ptr<int> (*is[2])(void) = {((void *)0)};
3434
//CHECK_NOALL: _Ptr<int> (*i)(void) = ((void *)0);
3535
//CHECK_ALL: _Ptr<_Ptr<int> (void)> is _Checked[2] = {((void *)0)};
3636
//CHECK_ALL: _Ptr<_Ptr<int> (void)> i = ((void *)0);
3737

3838
int *(**js[2])(void);
3939
int *(**j)(void);
40-
//CHECK_NOALL: _Ptr<int> (** js[2])(void) = {((void *)0)};
40+
//CHECK_NOALL: _Ptr<int> (**js[2])(void) = {((void *)0)};
4141
//CHECK_NOALL: _Ptr<int> (**j)(void) = ((void *)0);
4242
//CHECK_ALL: _Ptr<_Ptr<_Ptr<int> (void)>> js _Checked[2] = {((void *)0)};
4343
//CHECK_ALL: _Ptr<_Ptr<_Ptr<int> (void)>> j = ((void *)0);
4444

4545
int *(*ks[2][2])(void);
4646
int *(*k)(void);
47-
//CHECK_NOALL: _Ptr<int> (* ks[2][2])(void) = {((void *)0)};
47+
//CHECK_NOALL: _Ptr<int> (*ks[2][2])(void) = {((void *)0)};
4848
//CHECK_NOALL: _Ptr<int> (*k)(void) = ((void *)0);
4949
//CHECK_ALL: _Ptr<_Ptr<int> (void)> ks _Checked[2] _Checked[2] = {((void *)0)};
5050
//CHECK_ALL: _Ptr<_Ptr<int> (void)> k = ((void *)0);

clang/test/3C/generalize.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ void nameless(void *a, char *b)
4848
{
4949
a = 1; // make it unsafe
5050
}
51-
// CHECK: void nameless(void * a, _Ptr<char> b);
51+
// CHECK: void nameless(void *a, _Ptr<char> b);
5252
// CHECK: void nameless(void *a, _Ptr<char> b)
5353

5454
// Safe functions should be upgraded from "_Itype_for_any" to "_For_any"

clang/test/3C/macro_end_of_decl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ int *f EQ 0;
3838

3939
int(*g0) ARGS, g1 SIZE, *g2 EQ 0;
4040
//CHECK: _Ptr<int (void)> g0 = ((void *)0);
41-
//CHECK_NOALL: int g1[1];
41+
//CHECK_NOALL: int g1 SIZE;
4242
//CHECK_ALL: int g1 _Checked SIZE;
4343
//CHECK: _Ptr<int> g2 = 0;
4444

clang/test/3C/ptr_array.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ void test1(int *a) {
2828

2929
int *b[1] = {a};
3030
//CHECK_NOALL: int *b[1] = {a};
31-
//CHECK_ALL: int * b _Checked[1] = {a};
31+
//CHECK_ALL: int *b _Checked[1] = {a};
3232
}
3333

3434
/* Example from from the issue */
@@ -40,7 +40,7 @@ int *foo() {
4040
int z = 3;
4141
int *ptrs[4] = {&x, &y, &z, (int *)5};
4242
//CHECK_NOALL: int *ptrs[4] = {&x, &y, &z, (int *)5};
43-
//CHECK_ALL: int * ptrs _Checked[4] = {&x, &y, &z, (int *)5};
43+
//CHECK_ALL: int *ptrs _Checked[4] = {&x, &y, &z, (int *)5};
4444
int *ret;
4545
//CHECK: int *ret;
4646
for (int i = 0; i < 4; i++) {

0 commit comments

Comments
 (0)