<HTML><HEAD><TITLE>Samsung Enterprise Portal mySingle</TITLE>
<META content=IE=5 http-equiv=X-UA-Compatible>
<META content="text/html; charset=windows-1252" http-equiv=Content-Type>
<STYLE id=mysingle_style type=text/css>P {
        MARGIN-BOTTOM: 5px; FONT-SIZE: 9pt; FONT-FAMILY: Arial, arial; MARGIN-TOP: 5px
}
TD {
        MARGIN-BOTTOM: 5px; FONT-SIZE: 9pt; FONT-FAMILY: Arial, arial; MARGIN-TOP: 5px
}
LI {
        MARGIN-BOTTOM: 5px; FONT-SIZE: 9pt; FONT-FAMILY: Arial, arial; MARGIN-TOP: 5px
}
BODY {
        FONT-SIZE: 9pt; FONT-FAMILY: Arial, arial; MARGIN: 10px; LINE-HEIGHT: 1.4
}
</STYLE>

<META name=GENERATOR content=ActiveSquare></HEAD>
<BODY>
<P> </P>
<P>Hi Richard,</P>
<P> </P>
<P>Thanks for your inputs.</P>
<P>As per review comments, I am now checking if the element contained in the InitList is an ICE.</P>
<P>Also added a test in constant-expression.cpp. </P>
<P>Please comment for further improvements.</P>
<P> </P>
<P>Patch:</P>
<P> </P>
<P>Index: test/SemaCXX/constant-expression.cpp<BR>===================================================================<BR>--- test/SemaCXX/constant-expression.cpp (revision 199888)<BR>+++ test/SemaCXX/constant-expression.cpp (working copy)<BR>@@ -124,3 +124,12 @@<BR>   struct Y { bool b; X x; }; // expected-error {{field has incomplete type 'test3::X'}}<BR>   int f() { return Y().b; }<BR> }<BR>+<BR>+// PR18283<BR>+namespace test4 {<BR>+  template <int> struct A {};<BR>+  int const i = { 42 };<BR>+  // i can be used as non-type template-parameter as "const int x = { 42 };" is<BR>+  // equivalent to "const int x = 42;" as per C++03 8.5/p13.<BR>+  typedef A<i> Ai; // ok<BR>+}<BR>Index: lib/AST/ExprConstant.cpp<BR>===================================================================<BR>--- lib/AST/ExprConstant.cpp (revision 199888)<BR>+++ lib/AST/ExprConstant.cpp (working copy)<BR>@@ -8331,7 +8331,14 @@<BR>   case Expr::MaterializeTemporaryExprClass:<BR>   case Expr::PseudoObjectExprClass:<BR>   case Expr::AtomicExprClass:<BR>-  case Expr::InitListExprClass:<BR>+  case Expr::InitListExprClass: {<BR>+    // C++03 8.5/13 says that If T is a scalar type, then a declaration of the<BR>+    // form "T x = { a };" is equivalent to "T x = a;". T is a scalar as it is  <BR>+    // known to be of integral or enumeration type.<BR>+    if (E->isRValue())<BR>+      if (cast<InitListExpr>(E)->getNumInits() == 1)<BR>+        return CheckICE(cast<InitListExpr>(E)->getInit(0), Ctx);<BR>+  }<BR>   case Expr::LambdaExprClass:<BR>     return ICEDiag(IK_NotICE, E->getLocStart());</P>
<P> </P>
<P>Thanks,</P>
<P>Rahul</P>
<P> </P>
<P>------- <B>Original Message</B> -------</P>
<P><B>Sender</B> : Richard Smith<metafoo@gmail.com></P>
<P><B>Date</B> : Jan 24, 2014 04:00 (GMT+05:30)</P>
<P><B>Title</B> : [PATCH] Fix for 18283 - Const int initialized with curly braces is not a compile time constant</P>
<P> </P>
<DIV>On Thu Jan 23 2014 at 2:24:25 AM, Rahul Jain <<A href="mailto:rahul1.jain@samsung.com">rahul1.jain@samsung.com</A>> wrote:</DIV>
<BLOCKQUOTE class=gmail_quote style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">
<DIV>
<P> </P>
<P>Thanks Marshal and Richard for the valuable inputs.</P>
<P> </P>
<P>Hi Richard,</P>
<P> </P>
<P>I have implemented a patch as per your suggestion, adding a check to</P>
<P>handle the case of InitListExpr, when it is used as an RValue.</P>
<P> </P>
<P>Please if you could review it and suggest improvements.</P></DIV></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>The patch needs a corresponding regression test to be added to some file in tests/. test/SemaCXX/constant-expression.cpp seems like a good place.</DIV>
<DIV><BR></DIV>
<BLOCKQUOTE class=gmail_quote style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">
<DIV>
<P>Index: tools/clang/lib/AST/ExprConstant.cpp<BR>===================================================================<BR>--- tools/clang/lib/AST/ExprConstant.cpp (revision 199874)<BR>+++ tools/clang/lib/AST/ExprConstant.cpp (working copy)<BR>@@ -8331,7 +8331,14 @@<BR>   case Expr::MaterializeTemporaryExprClass:<BR>   case Expr::PseudoObjectExprClass:<BR>   case Expr::AtomicExprClass:<BR>-  case Expr::InitListExprClass:<BR>+  case Expr::InitListExprClass: {<BR>+    // Fix for PR 18283, if InitListExpr is used as an RValue containing<BR>+    // only one scalar value, it is an ICE.<BR></P></DIV></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>Don't reference a PR number here; the code should be able to justify its existence without reference to bugs. Instead, you can say that C++03 [dcl.init]p13 says that "T x = { a };" is equivalent to "T x = a;" when T is a scalar type (and maybe point out that T must be a scalar type because we know it's an integral or enumeration type). You should reference the PR number in the test case, instead.</DIV>
<DIV><BR></DIV>
<BLOCKQUOTE class=gmail_quote style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">
<DIV>
<P>+    if (E->isRValue())<BR>+      if (cast<InitListExpr>(E)->getNumInits() == 1)<BR>+        return NoDiag();             <BR></P></DIV></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>This isn't correct -- you can't assume that any braced initialization is a constant expression. Instead, call CheckICE on the subexpression.</DIV>
<DIV><BR></DIV>
<BLOCKQUOTE class=gmail_quote style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">
<DIV>
<P>+  }<BR>+<BR>   case Expr::LambdaExprClass:<BR>     return ICEDiag(IK_NotICE, E->getLocStart());</P>
<P><BR> </P>
<P>Thanks,</P>
<P>Rahul</P>
<P> </P>
<P>------- <B>Original Message</B> -------</P>
<P><B>Sender</B> : Richard Smith<<A href="mailto:richard@metafoo.co.uk" target=_blank>richard@metafoo.co.uk</A>></P>
<P><B>Date</B> : Jan 23, 2014 01:12 (GMT+05:30)</P>
<P><B>Title</B> : Re: [cfe-dev] <U></U>C++ 03 - Need clarification regarding non-type template argument</P>
<P> </P>
<DIV dir=ltr>
<DIV>
<DIV>On Wed, Jan 22, 2014 at 11:22 AM, Marshall Clow <SPAN dir=ltr><<A href="mailto:mclow.lists@gmail.com" target=_blank>mclow.lists@gmail.com</A>></SPAN> wrote:<BR>
<BLOCKQUOTE style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: rgb(204,204,204) 1px solid">
<DIV style="WORD-WRAP: break-word"><BR>
<DIV>
<DIV>
<DIV>On Jan 21, 2014, at 5:59 AM, Rahul Jain <<A href="mailto:rahul1.jain@samsung.com" target=_blank>rahul1.jain@samsung.com</A>> wrote:</DIV><BR>
<BLOCKQUOTE type="cite">
<DIV style="WHITE-SPACE: normal; TEXT-TRANSFORM: none; WORD-SPACING: 0px; FONT: 9pt/1.4 Arial,arial; MARGIN: 10px; LETTER-SPACING: normal; TEXT-INDENT: 0px">
<DIV style="MARGIN-BOTTOM: 5px; FONT-SIZE: 9pt; FONT-FAMILY: Arial,arial; MARGIN-TOP: 5px"><BR> </DIV>
<P style="MARGIN-BOTTOM: 5px; FONT-SIZE: 9pt; FONT-FAMILY: Arial,arial; MARGIN-TOP: 5px">Hi all,</P>
<DIV style="MARGIN-BOTTOM: 5px; FONT-SIZE: 9pt; FONT-FAMILY: Arial,arial; MARGIN-TOP: 5px"><BR> </DIV>
<DIV>Note - this is with respect to C++ 03.</DIV>
<DIV></DIV>
<DIV><EM></EM> </DIV>
<DIV><EM>Test code:</EM></DIV>
<DIV><EM></EM> </DIV>
<DIV><EM>template <int> struct A {};<BR>int const i = {42};<BR>typedef A<i> Ai;</EM></DIV></DIV></BLOCKQUOTE>
<DIV><BR></DIV></DIV>Short, snarky answer - you can’t bracket-initialize a variable in c++03</DIV></DIV></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>You can in a few cases: specifically, if the type is an aggregate or a scalar type. In the latter case,</DIV>
<DIV><BR></DIV>
<DIV>   T x = { a };</DIV>
<DIV><BR></DIV>
<DIV>is equivalent to</DIV>
<DIV><BR></DIV>
<DIV>  T x = a;</DIV>
<DIV><BR></DIV>
<DIV>(See C++03 [dcl.init](8.5)/13.)</DIV>
<DIV> </DIV>
<BLOCKQUOTE style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: rgb(204,204,204) 1px solid">
<DIV style="WORD-WRAP: break-word">
<DIV>
<DIV><SPAN style="WHITE-SPACE: pre-wrap"></SPAN>int const i = {42};</DIV>
<DIV><BR></DIV></DIV>
<DIV>
<DIV>
<BLOCKQUOTE type="cite">
<DIV style="WHITE-SPACE: normal; TEXT-TRANSFORM: none; WORD-SPACING: 0px; FONT: 9pt/1.4 Arial,arial; MARGIN: 10px; LETTER-SPACING: normal; TEXT-INDENT: 0px">
<DIV>For non-type template argument, standard (C++ 03) says that:</DIV>
<DIV></DIV>
<DIV><EM>14.3.2 / 1</EM></DIV>
<P style="MARGIN-BOTTOM: 5px; FONT-SIZE: 9pt; FONT-FAMILY: Arial,arial; MARGIN-TOP: 5px"><EM>A template-argument for a non-type, non-template template-parameter shall be one of:</EM></P>
<UL><EM></EM>
<LI style="MARGIN-BOTTOM: 5px; FONT-SIZE: 9pt; FONT-FAMILY: Arial,arial; MARGIN-TOP: 5px"><EM>an<SPAN> </SPAN><STRONG>integral constant-expression</STRONG><SPAN> </SPAN>of integral or enumeration type; or ......</EM></LI></UL>
<DIV>For the test code above, the statement '<EM>typedef A<i> Ai</EM>', should the compiler</DIV>
<DIV>check the rhs (rvalue) of variable 'i' to determine if it is a constant or not?</DIV></DIV></BLOCKQUOTE></DIV></DIV></DIV></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>Yes. For 'i' to be an integral constant-expression, it can only mention "const variables [...] of integral or enumeration types initialized with constant expressions" (C++03 [expr.const](5.19)/1). So the compiler is required to check whether 'i' is indeed initialized by a constant expression.</DIV>
<DIV><BR></DIV>
<BLOCKQUOTE style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: rgb(204,204,204) 1px solid">
<DIV style="WORD-WRAP: break-word">
<DIV>
<DIV>
<BLOCKQUOTE type="cite">
<DIV style="WHITE-SPACE: normal; TEXT-TRANSFORM: none; WORD-SPACING: 0px; FONT: 9pt/1.4 Arial,arial; MARGIN: 10px; LETTER-SPACING: normal; TEXT-INDENT: 0px">
<DIV>Shouldnt it just check the type of i (which is declared as const)?</DIV>
<DIV>Whether 'i' evaluates to constant (at compile time) or not should be the responsibility of compiler</DIV>
<DIV>while processing statement '<EM>int const i = {42}</EM>' and not '<EM>typedef A<i> Ai' ? Isnt it?</EM></DIV>
<DIV> </DIV>
<DIV>Another analogy:<BR>For arrays, the size of the array needs to be a compile time constant. So, the following code :</DIV>
<DIV></DIV>
<DIV><EM></EM> </DIV>
<DIV><EM>int const x = 42;</EM></DIV>
<DIV><EM>int z[x];</EM></DIV>
<DIV></DIV>
<DIV> </DIV>
<DIV>For the statement<SPAN> </SPAN><EM>'int z[x]'</EM>, will the compiler evaluate the rhs of<SPAN> </SPAN><EM>'x'</EM><SPAN> </SPAN>to check if it evaluates to constant at runtime</DIV>
<DIV>or will it just see that '<EM>x</EM>' is of 'integer const' type and hence there is no problem with the array declaration?</DIV>
<DIV>Whether '<EM>x</EM>' evaluates to constant should be the responsibility of compiler while processing statement '<EM>int const x=42</EM>'</DIV>
<DIV>and not while processing '<EM>int z[x]</EM>' ?</DIV>
<DIV></DIV>
<DIV> </DIV>
<DIV>Should this analogy be applicable to non-type template argument?</DIV></DIV></BLOCKQUOTE></DIV></DIV></DIV></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>According to the C++ standard, the two cases are exactly the same. However, to support code relying on GCC extensions, we allow any constant-foldable expression as an array bound, whereas we require a constant-expression as a template argument. Use -pedantic-errors to enable Clang's strictly-conforming mode, where we (incorrectly) reject both cases.</DIV>
<DIV><BR></DIV>
<DIV>The bug is that CheckICE in lib/AST/ExprConstant.cpp (or maybe VarDecl::checkInitIsICE) doesn't handle the case of an InitListExpr being used to initialize a scalar.</DIV>
<DIV><BR></DIV>
<BLOCKQUOTE style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: rgb(204,204,204) 1px solid">
<DIV style="WORD-WRAP: break-word">
<DIV>
<DIV>
<BLOCKQUOTE type="cite">
<DIV style="WHITE-SPACE: normal; TEXT-TRANSFORM: none; WORD-SPACING: 0px; FONT: 9pt/1.4 Arial,arial; MARGIN: 10px; LETTER-SPACING: normal; TEXT-INDENT: 0px">
<DIV></DIV>
<P style="MARGIN-BOTTOM: 5px; FONT-SIZE: 9pt; FONT-FAMILY: Arial,arial; MARGIN-TOP: 5px">Please throw some light on this, am I missing any particular case?</P></DIV></BLOCKQUOTE><BR></DIV></DIV>
<DIV>My understanding (which may be flawed) is that the compiler needs to see both:</DIV>
<DIV>* That the compiler needs to be able to determine that the value it needs is const</DIV>
<DIV>* That the compiler can see what the value actually is, so that it can allocate space for the array, or instantiate the template.</DIV>
<DIV><BR></DIV>
<DIV><BR></DIV>
<DIV>So, this would not work:</DIV>
<DIV><BR></DIV><SPAN style="WHITE-SPACE: pre-wrap"></SPAN>extern const int i; 
<DIV><SPAN style="WHITE-SPACE: pre-wrap"></SPAN>template <int> struct A {};<BR><SPAN style="WHITE-SPACE: pre-wrap"></SPAN>typedef A<i> Ai;</DIV></DIV></BLOCKQUOTE>
<DIV><BR></DIV>
<DIV>Right. </DIV></DIV></DIV></DIV>
<P> </P>
<P> </P>
<P> </P>
<TABLE>
<TBODY>
<TR>
<TD>
<P><IMG border=0 src="cid:Z5JE7EUABGFC@namo.co.kr" width=520></P></TD></TR></TBODY></TABLE></DIV><IMG border=0 src="http://ext.samsung.net/mailcheck/SeenTimeChecker?do=138117183f8501de87a76644c0563226b38ca38a19637fd57fd152fcb9c0a7b71949e5361b5b07078e8c935117e1541af8ae1b241f6e633f08cece8541bc14eacf878f9a26ce15a0" width=0 height=0></BLOCKQUOTE>
<P> </P>
<P> </P><!--SP:rahul1.jain--><!--rahul1.jain:EP-->
<P> </P>
<TABLE id=confidentialsignimg>
<TBODY>
<TR>
<TD NAMO_LOCK>
<P><IMG border=0 src="cid:LK7CT9SZN3WZ@namo.co.kr" width=520></P></TD></TR></TBODY></TABLE></BODY></HTML><img src='http://ext.samsung.net/mailcheck/SeenTimeChecker?do=138117183f8501de249d92c6b5635fb1975cffd5c3522514e56225dd835e375f5f887f84397989de4b5562a776ba3bf30029dc535ebebcd3326bbdfb2ea96a2fcf878f9a26ce15a0' border=0 width=0 height=0 style='display:none'>