Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Issue 9198 - Vararg functions don't respect IFTI rules #1399

Merged
merged 1 commit into from

3 participants

@ghost

Btw, have we ever documented this behavior in the spec? People seem to be surprised by it so it should be documented if it's not.

@9rnsr
Collaborator

As far as I know this is yet not documented in website. So I agree with its necessity.
As an additional note, the behavior respects the IFTI rule in C++. So it is not D-specific rule.

template<class T>
void foo(T t){ t = 0; }  // OK, because typeof(t) == const(int)*
void bar(int const *const p) { p = 0; }  // error: assignment of read-only parameter 'p'
int main() {
    int x;
    int const *const p = &x;  // typeof(p) == const(int*)
    foo(p);
    bar(p);
    return 0;
}
@monarchdodra

Touching to get notified when this gets pulled.

@WalterBright WalterBright merged commit 5f5ec27 into D-Programming-Language:master

1 check failed

Details default Pass: 4, Pending: 6
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 38 additions and 30 deletions.
  1. +9 −0 src/template.c
  2. +29 −30 test/runnable/template9.d
View
9 src/template.c
@@ -1344,6 +1344,15 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec
if (m < match)
match = m;
+ /* Remove top const for dynamic array types and pointer types
+ */
+ if ((tt->ty == Tarray || tt->ty == Tpointer) &&
+ !tt->isMutable() &&
+ (!(fparam->storageClass & STCref) ||
+ (fparam->storageClass & STCauto) && !farg->isLvalue()))
+ {
+ tt = tt->mutableOf();
+ }
t->objects[i] = tt;
}
declareParameter(paramscope, tp, t);
View
59 test/runnable/template9.d
@@ -937,45 +937,44 @@ template pow10_2550(long n:0)
static assert(pow10_2550!(0) == 1);
/**********************************/
+// [2.057] Remove top const in IFTI, 9198
+
+void foo10a(T )(T) { static assert(is(T == const(int)[])); }
+void foo10b(T...)(T) { static assert(is(T[0] == const(int)[])); }
+
+// ref paramter doesn't remove top const
+void boo10a(T )(ref T) { static assert(is(T == const(int[]))); }
+void boo10b(T...)(ref T) { static assert(is(T[0] == const(int[]))); }
+
+// auto ref with lvalue doesn't
+void goo10a(T )(auto ref T) { static assert(is(T == const(int[]))); }
+void goo10b(T...)(auto ref T) { static assert(is(T[0] == const(int[]))); }
+
+// auto ref with rvalue does
+void hoo10a(T )(auto ref T) { static assert(is(T == const(int)[])); }
+void hoo10b(T...)(auto ref T) { static assert(is(T[0] == const(int)[])); }
+
+void bar10a(T )(T) { static assert(is(T == const(int)*)); }
+void bar10b(T...)(T) { static assert(is(T[0] == const(int)*)); }
-void foo10(T)(T prm)
-{
- pragma(msg, T);
- static assert(is(T == const(int)[]));
-}
-void boo10(T)(ref T val) // ref paramter doesn't remove top const
-{
- pragma(msg, T);
- static assert(is(T == const(int[])));
-}
-void goo10(T)(auto ref T val) // auto ref with lvalue doesn't
-{
- pragma(msg, T);
- static assert(is(T == const(int[])));
-}
-void hoo10(T)(auto ref T val) // auto ref with rvalue does
-{
- pragma(msg, T);
- static assert(is(T == const(int)[]));
-}
-void bar10(T)(T prm)
-{
- pragma(msg, T);
- static assert(is(T == const(int)*));
-}
void test10()
{
const a = [1,2,3];
static assert(is(typeof(a) == const(int[])));
- foo10(a);
- boo10(a);
- goo10(a);
- hoo10(cast(const(int[]))[1,2,3]);
+ foo10a(a);
+ foo10b(a);
+ boo10a(a);
+ boo10b(a);
+ goo10a(a);
+ goo10b(a);
+ hoo10a(cast(const)[1,2,3]);
+ hoo10b(cast(const)[1,2,3]);
int n;
const p = &n;
static assert(is(typeof(p) == const(int*)));
- bar10(p);
+ bar10a(p);
+ bar10b(p);
}
/**********************************/
Something went wrong with that request. Please try again.