[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cfe-dev
Subject:    Re: [cfe-dev] Bug 18275 - Incorrect const qualifier behavior in definition.
From:       Richard Smith <metafoo () gmail ! com>
Date:       2014-01-30 19:13:09
Message-ID: -8525502931446802317 () gmail297201516
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


On Thu Jan 30 2014 at 6:21:34 AM, suyog sarda <sardask01@gmail.com> wrote:

> Ping !! Any help would be appreciated on this.
>
> On Thu, Jan 30, 2014 at 1:04 AM, suyog sarda <sardask01@gmail.com> wrote:
>
> Hi,
>
> I was looking at bug 18275 - Incorrect const qualifier behavior in
> definition.
>
> The declaration of A::f has a const. The definition doesn't.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> *template <typename T>struct A {    void f(const int);};template <typename
> T>void A<T>::f(int x){    x = 0;}void f(){    A<float> a;    a.f(0);}*
>
> Clang produces an error:
>
> test.cpp:10:7: error: read-only variable is not assignable
>     x = 0;
>     ~ ^
> test.cpp:26:7: note: in instantiation of member function 'A<float>::f'
> requested here
>     a.f(0);
>       ^
>
> It only happens for templateclasses. In exact the same situation with a
> regular class everything compiles well.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> *struct B{    void f(const int);};void B::f(int x){    x = 0;} void
> f(){    B b;    b.f(0);}*GCC compiles both examples without an error.
>
> According to my understanding, the standard 13.1/3 states that Parameter
> declarations that differ only in the presence or absence of const and/or
> volatile are equivalent. That is, the const and volatile type-specifiers
> for each parameter type are ignored when determining which function
> is being declared, defined, or called. So clang is wrong to throw error in
> template case.
>
> After following the code path for above examples, i came across function
> name "*Sema::ActOnFunctionDeclarator*" in SemaDecl.cpp file, where
> everytime a function is redeclared/defined, its new declaration is created '
> *CreateNewFunctionDecl*', and its parameters are copied in following
> lines of code (l*ine number 6890 in SemaDecl.cpp in latest trunk version*)
>
>
>
>
>
>
> *for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {        ParmVarDecl
> *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
> assert(Param->getDeclContext() != NewFD && "Was set before ?");
> Param->setDeclContext(NewFD);        Params.push_back(Param);*
> I couldn't find exactly where the codepath gets different for above two
> cases. For both TC above, parameters get copied in above lines of code. Can
> someone help in pointing out, where does the properties of function
> parameters/variables are set and where does those properties get reset on
> redeclaration/definition? Am i going wrong somewhere in above code analysis?
>
>
The above is what happens when we parse a function declaration /
definition, but it's not the code path taken during template instantiation.

When we instantiate a class template, we instantiate declarations of all
the member functions of that class template. When we later instantiate the
definition of one of those functions, we do not instantiate another
declaration (potentially with slightly different actual parameter types);
instead, we reuse the prior declaration.

Look into Sema::InstantiateFunctionDefinition, and in particular its call
to addInstantiatedParametersToScope, to see where we reuse the prior
parameters.

[Attachment #5 (text/html)]

<div>On Thu Jan 30 2014 at 6:21:34 AM, suyog sarda &lt;<a \
href="mailto:sardask01@gmail.com">sardask01@gmail.com</a>&gt; wrote:</div><blockquote \
class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc \
solid;padding-left:1ex"> Ping !! Any help would be appreciated on \
this.<br><br><div>On Thu, Jan 30, 2014 at 1:04 AM, suyog sarda <span dir="ltr">&lt;<a \
href="mailto:sardask01@gmail.com" target="_blank">sardask01@gmail.com</a>&gt;</span> \
wrote:<br>

<blockquote style="margin:0px 0px 0px \
0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><div \
dir="ltr">Hi,<br><br>I was looking at bug 18275 - Incorrect const qualifier behavior \
in definition.<br>

<br>The declaration of A::f has a const. The definition \
doesn&#39;t.<br><br><i>template &lt;typename T&gt;<br>struct A<br> {<br>    void \
f(const int);<br>};<br><br>template &lt;typename T&gt;<br>void A&lt;T&gt;::f(int \
x)<br>{<br>    x = 0;<br>}<br><br>void f()<br>{<br>    A&lt;float&gt; a;<br>    \
a.f(0);<br>}<br></i><br><br>Clang produces an error:<br>


<br>test.cpp:10:7: error: read-only variable is not assignable<br>    x = 0;<br>    ~ \
^<br>test.cpp:26:7: note: in instantiation of member function \
&#39;A&lt;float&gt;::f&#39;<br>requested here<br>    a.f(0);<br>      ^<br>


<br>It only happens for templateclasses. In exact the same situation with a regular \
class everything compiles well.<br><br><i>struct B<br>{<br>    void f(const \
int);<br>};<br><br>void B::f(int x)<br>{<br>    x = 0;<br>}<br>


<br>void f()<br>{<br>    B b;<br>    b.f(0);<br>}<br><br></i>GCC compiles both \
examples without an error.<br><br>According to my understanding, the standard 13.1/3 \
states that Parameter declarations that differ only in the presence or absence of \
const and/or volatile are equivalent. That is, the const and volatile type-specifiers \
for each parameter type are ignored when determining which function<br>


is being declared, defined, or called. So clang is wrong to throw error in template \
case.<br><br>After following the code path for above examples, i came across function \
name &quot;<i>Sema::ActOnFunctionDeclarator</i>&quot; in SemaDecl.cpp file, where \
everytime a function is redeclared/defined, its new declaration is created \
&#39;<i>CreateNewFunctionDecl</i>&#39;, and its parameters are copied in following \
lines of code (l<i>ine number 6890 in SemaDecl.cpp in latest trunk version</i>)<br>


<br><i>for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {<br>        ParmVarDecl \
*Param = cast&lt;ParmVarDecl&gt;(FTI.ArgInfo[i].Param);<br>        \
assert(Param-&gt;getDeclContext() != NewFD &amp;&amp; &quot;Was set before \
?&quot;);<br>


        Param-&gt;setDeclContext(NewFD);<br>        \
Params.push_back(Param);<br></i><br>I couldn&#39;t find exactly where the codepath \
gets different for above two cases. For both TC above, parameters get copied in above \
lines of code. Can someone help in pointing out, where does the properties of \
function parameters/variables are set and where does those properties get reset on \
redeclaration/definition? Am i going wrong somewhere in above code analysis?</div> \
</blockquote></div></blockquote><div><br></div><div>The above is what happens when we \
parse a function declaration / definition, but it&#39;s not the code path taken \
during template instantiation.</div><div><br></div><div> When we instantiate a class \
template, we instantiate declarations of all the member functions of that class \
template. When we later instantiate the definition of one of those functions, we do \
not instantiate another declaration (potentially with slightly different actual \
parameter types); instead, we reuse the prior declaration.</div> \
<div><br></div><div>Look into Sema::InstantiateFunctionDefinition, and in particular \
its call to addInstantiatedParametersToScope, to see where we reuse the prior \
parameters.</div>



_______________________________________________
cfe-dev mailing list
cfe-dev@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic