[PATCH] PR64959: SFINAE in UDLs

2015-02-09 Thread Andrea Azzarone
Hi all,

atm enable_if cannot be used to select between overload of UDLs. E.g.
https://gcc.gnu.org/bugzilla/attachment.cgi?id=34684 will not compile.
This can be easily fixed making sure that lookup_literal_operator
returns all the possible candidates and not just the first match. I
made some more changes in parser.c to improve diagnostic in case of
failures. Four testcases added:
* udlit-sfinae.C
* udlit-sfinae.neg.C
* udlit-char-template-sfinae.C
* udlit-char-template-sfinae-neg.C

The first make check showed a failures in udlit-resolve.C. Actually
the failures was a false positive, because UDLs lookup is a normal
unqualified name lookup. I added two tests:
  * udlit-namespace-ambiguous.C
  * udlit-namespace-ambiguous-neg.C

At the end I also noticed a bug in string template literals. As per
N3599 the lookup should give precedence to operator""_t(const char*,
unsigned long). I updated the code in parser.C and added a test.

Please note that this is my first gcc patch :)

2015-2-9 Andrea Azzarone 
PR c++/64959

* gcc/cp/parser.c: Make sure lookup_literal_operator returns all
the possible candidates. Also improve the diagnostic messages.
* gcc/testsuite/g++.dg/cpp0x/udlit-namespace-ambiguous.C: Add test
case to make sure gcc detects ambiguous UDL declarations.
* gcc/testsuite/g++.dg/cpp0x/udlit-namespace-using-directive.C:
Add test case to make sure gcc correctly handles using directive for
UDLs.
* gcc/testsuite/g++.dg/cpp0x/udlit-resolve.C: Remove a incorrect test case.
* gcc/testsuite/g++.dg/cpp0x/udlit-sfinae.C: Add a test case to
make sure that enable_if can be used to select between overloads of
UDLs.
* gcc/testsuite/g++.dg/cpp0x/udlit-sfinae-neg.C: Add a test case
to make sure gcc correctly detects substitution failures when all the
UDSL overloads are disabled by enable_if.
* gcc/testsuite/g++.dg/cpp1y/udlit-char-template-sfinae-neg.C:
Like cpp0x/udlit-sfinae-neg.C but for string template literals.
* gcc/testsuite/g++.dg/cpp1y/udlit-char-template-sfinae.C: Like
cpp0x/udlit-sfinae.C but for string template literals.
* gcc/testsuite/g++.dg/cpp1y/udlit-char-template-vs-std-literal-operator.C:
Add a test to make sure that string template literals have a smaller
priority than standard literal operators.


-- 
Andrea Azzarone
Index: gcc/cp/parser.c
===
--- gcc/cp/parser.c (revision 220454)
+++ gcc/cp/parser.c (working copy)
@@ -3828,7 +3828,7 @@ lookup_literal_operator (tree name, vec<
 work in presence of default arguments on the literal
 operator parameters.  */
  && parmtypes == void_list_node)
-   return fn;
+   return decl;
}
 }
 
@@ -3955,7 +3955,7 @@ cp_parser_userdef_numeric_literal (cp_pa
   decl = lookup_literal_operator (name, args);
   if (decl && decl != error_mark_node)
 {
-  result = finish_call_expr (decl, &args, false, true, tf_none);
+  result = finish_call_expr (decl, &args, false, true, 
tf_warning_or_error);
   if (result != error_mark_node)
{
  if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE && overflow > 0)
@@ -3986,7 +3986,7 @@ cp_parser_userdef_numeric_literal (cp_pa
   decl = lookup_literal_operator (name, args);
   if (decl && decl != error_mark_node)
 {
-  result = finish_call_expr (decl, &args, false, true, tf_none);
+  result = finish_call_expr (decl, &args, false, true, 
tf_warning_or_error);
   if (result != error_mark_node)
{
  release_tree_vector (args);
@@ -4004,13 +4004,12 @@ cp_parser_userdef_numeric_literal (cp_pa
 {
   tree tmpl_args = make_char_string_pack (num_string);
   decl = lookup_template_function (decl, tmpl_args);
-  result = finish_call_expr (decl, &args, false, true, tf_none);
-  if (result != error_mark_node)
-   {
- release_tree_vector (args);
- return result;
-   }
+  result = finish_call_expr (decl, &args, false, true, 
tf_warning_or_error);
+
+  release_tree_vector (args);
+  return result;
 }
+
   release_tree_vector (args);
 
   error ("unable to find numeric literal operator %qD", name);
@@ -4035,6 +4034,24 @@ cp_parser_userdef_string_literal (tree l
   tree decl, result;
   vec *args;
 
+  /* Build up a call to the user-defined operator  */
+  /* Lookup the name we got back from the id-expression.  */
+  args = make_tree_vector ();
+  vec_safe_push (args, value);
+  vec_safe_push (args, build_int_cst (size_type_node, len));
+  decl = lookup_literal_operator (name, args);
+
+  if (decl && decl != error_mark_node)
+{
+  result = finish_call_expr (decl, &args, false, true, 
tf_warning_or_error);
+  if (result != error_mark_node)
+{
+  release_tree_vector (args);
+  return result;
+}
+}
+  

Re: [PATCH] PR64959: SFINAE in UDLs

2015-02-10 Thread Andrea Azzarone
Hi,

Thanks for the review. I updated the patch.

2015-2-9 Andrea Azzarone 
PR c++/64959

* parser.c (lookup_literal_operator): Return all candidates.
  (cp_parser_userdef_char_literal): Simplify error handling.
  (cp_parser_userdef_numeric_literal):  Pass tf_warning_or_error.
  (cp_parser_userdef_string_literal): Pass tf_warning_or_error.
Also give higher priority to standard string UDL operator.

* gcc/testsuite/g++.dg/cpp0x/udlit-namespace-ambiguous.C: Added
test case to make sure gcc detects ambiguous UDL declarations.
* gcc/testsuite/g++.dg/cpp0x/udlit-namespace-using-directive.C:
Added test case to make sure gcc correctly handles using directive for
UDLs.
* gcc/testsuite/g++.dg/cpp0x/udlit-resolve.C: Removed a incorrect test case.
* gcc/testsuite/g++.dg/cpp0x/udlit-sfinae.C: Added a test case to
make sure that enable_if can be used to select between overloads of
UDLs.
* gcc/testsuite/g++.dg/cpp0x/udlit-sfinae-neg.C: Added a test case
to make sure gcc correctly detects substitution failures when all the
UDSL overloads are disabled by enable_if.
* gcc/testsuite/g++.dg/cpp1y/udlit-char-template-sfinae-neg.C:
Like cpp0x/udlit-sfinae-neg.C but for string template literals.
* gcc/testsuite/g++.dg/cpp1y/udlit-char-template-sfinae.C: Like
cpp0x/udlit-sfinae.C but for string template literals.
* gcc/testsuite/g++.dg/cpp1y/udlit-char-template-vs-std-literal-operator.C:
Added a test to make sure that string template literals have a smaller
priority than standard literal operators.

2015-02-10 18:18 GMT+01:00 Jason Merrill :
> On 02/09/2015 08:27 AM, Andrea Azzarone wrote:
>>
>> Please note that this is my first gcc patch
>
>
> Thanks, looks good!  A couple of nits:
>
>> * gcc/cp/parser.c: Make sure lookup_literal_operator returns all
>> the possible candidates. Also improve the diagnostic messages.
>
>
> A ChangeLog entry should be per function, e.g.
>
> * parser.c (lookup_literal_operator): Return all candidates.
> (cp_parser_userdef_numeric_literal): Pass tf_warning_or_error.
> (cp_parser_userdef_string_literal): Likewise.  Prefer the
> non-template form.
>
>> @@ -4044,31 +4061,15 @@ cp_parser_userdef_string_literal (tree l
>>  {
>>tree tmpl_args = make_string_pack (value);
>>decl = lookup_template_function (decl, tmpl_args);
>> -  result = finish_call_expr (decl, &args, false, true, tf_none);
>> +  result = finish_call_expr (decl, &args, false, true,
>> tf_warning_or_error);
>>if (result != error_mark_node)
>> -   {
>> - release_tree_vector (args);
>> - return result;
>> -   }
>> +{
>> +  release_tree_vector (args);
>> +  return result;
>> +}
>>  }
>
>
> Why not remove the test against error_mark_node here like you did in
> cp_parser_userdef_numeric_literal?
>
> Jason
>



-- 
Andrea Azzarone
http://launchpad.net/~andyrock
http://wiki.ubuntu.com/AndreaAzzarone
Index: gcc/cp/parser.c
===
--- gcc/cp/parser.c (revision 220454)
+++ gcc/cp/parser.c (working copy)
@@ -3828,7 +3828,7 @@ lookup_literal_operator (tree name, vec<
 work in presence of default arguments on the literal
 operator parameters.  */
  && parmtypes == void_list_node)
-   return fn;
+   return decl;
}
 }
 
@@ -3862,12 +3862,7 @@ cp_parser_userdef_char_literal (cp_parse
 }
   result = finish_call_expr (decl, &args, false, true, tf_warning_or_error);
   release_tree_vector (args);
-  if (result != error_mark_node)
-return result;
-
-  error ("unable to find character literal operator %qD with %qT argument",
-name, TREE_TYPE (value));
-  return error_mark_node;
+  return result;
 }
 
 /* A subroutine of cp_parser_userdef_numeric_literal to
@@ -3955,26 +3950,27 @@ cp_parser_userdef_numeric_literal (cp_pa
   decl = lookup_literal_operator (name, args);
   if (decl && decl != error_mark_node)
 {
-  result = finish_call_expr (decl, &args, false, true, tf_none);
-  if (result != error_mark_node)
+  result = finish_call_expr (decl, &args, false, true, 
tf_warning_or_error);
+
+  if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE && overflow > 0)
{
- if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE && overflow > 0)
+ warning_at (token->location, OPT_Woverflow,
+ "integer literal exceeds range of %qT type",
+ long_long_unsigned_type_node);
+   }
+  else
+   {
+ if (overflow > 0)
+   warning_at (token->location, OPT_Wover

[C++] [PATCH] - Nested namespace defintions

2015-02-12 Thread Andrea Azzarone
Hi all,

would be nice to have nested namespace definitions in gcc. I'm not
sure if this if it's possible to merge stuff like this at this stage.

2015-2-13 Andrea Azzarone 
  PR c++/65047

  * gcc/cp/cp-tree.h Declare maybe_warn_cpp1z.
  * gcc/cp/error.c Define maybe_warn_cpp1z.
  * gcc/cp/parser.c (cp_parser_namespace_definition) Add support for
nested namespace definitions.

I did a full boostrap + full make check.

Thanks.

-- 
Andrea Azzarone
Index: gcc/cp/cp-tree.h
===
--- gcc/cp/cp-tree.h(revision 220454)
+++ gcc/cp/cp-tree.h(working copy)
@@ -467,6 +467,13 @@ typedef enum cpp0x_warn_str
   CPP0X_REF_QUALIFIER
 } cpp0x_warn_str;
 
+/* The various kinds of C++1z warnings we ecounter. */
+typedef enum cpp1z_warn_str
+{
+  /* nested namespace definitions. */
+  CPP1Z_NESTED_NAMESPACE_DEFINITIONS
+} cpp1z_warn_str;
+
 /* The various kinds of operation used by composite_pointer_type. */
 
 typedef enum composite_pointer_operation
@@ -5518,6 +5525,7 @@ extern const char *language_to_string (
 extern const char *class_key_or_enum_as_string (tree);
 extern void maybe_warn_variadic_templates   (void);
 extern void maybe_warn_cpp0x   (cpp0x_warn_str str);
+extern void maybe_warn_cpp1z   (cpp1z_warn_str str);
 extern bool pedwarn_cxx98   (location_t, int, const char 
*, ...) ATTRIBUTE_GCC_DIAG(3,4);
 extern location_t location_of   (tree);
 extern void qualified_name_lookup_error(tree, tree, tree,
Index: gcc/cp/error.c
===
--- gcc/cp/error.c  (revision 220454)
+++ gcc/cp/error.c  (working copy)
@@ -3611,6 +3611,24 @@ maybe_warn_cpp0x (cpp0x_warn_str str)
   }
 }
 
+void
+maybe_warn_cpp1z (cpp1z_warn_str str)
+{
+  if (cxx_dialect >= cxx1z)
+return;
+
+  switch (str)
+{
+case CPP1Z_NESTED_NAMESPACE_DEFINITIONS:
+  pedwarn (input_location, 0,
+  "nested namespace definitions "
+  "only available with -std=c++1z or -std=gnu=c++1z");
+  break;
+default:
+  gcc_unreachable ();
+}
+}
+
 /* Warn about the use of variadic templates when appropriate.  */
 void
 maybe_warn_variadic_templates (void)
Index: gcc/cp/parser.c
===
--- gcc/cp/parser.c (revision 220454)
+++ gcc/cp/parser.c (working copy)
@@ -16169,6 +16169,7 @@ cp_parser_namespace_name (cp_parser* par
namespace-definition:
  named-namespace-definition
  unnamed-namespace-definition
+ nested-namespace-definition
 
named-namespace-definition:
  original-namespace-definition
@@ -16181,24 +16182,32 @@ cp_parser_namespace_name (cp_parser* par
  namespace original-namespace-name { namespace-body }
 
unnamed-namespace-definition:
- namespace { namespace-body } */
+ namespace { namespace-body }
+
+   nested-namespace-definition:
+ namespace enclosing-namespace-specifier :: identifier { namespace-body } 
+
+   enclosing-namespace-specifier:
+ identifier
+ enclosing-namespace-specifier :: identifier */
 
 static void
 cp_parser_namespace_definition (cp_parser* parser)
 {
+  vec extra_identifiers;
   tree identifier, attribs;
   bool has_visibility;
-  bool is_inline;
+  location_t inline_location;
+  unsigned ns_deepness;
 
   cp_ensure_no_omp_declare_simd (parser);
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_INLINE))
 {
   maybe_warn_cpp0x (CPP0X_INLINE_NAMESPACES);
-  is_inline = true;
-  cp_lexer_consume_token (parser->lexer);
+  inline_location = cp_lexer_consume_token (parser->lexer)->location;
 }
   else
-is_inline = false;
+inline_location = UNKNOWN_LOCATION;
 
   /* Look for the `namespace' keyword.  */
   cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
@@ -16207,22 +16216,64 @@ cp_parser_namespace_definition (cp_parse
  between an original-namespace-definition and an
  extension-namespace-definition at this point.  The semantic
  analysis routines are responsible for that.  */
+  extra_identifiers.create(0);
   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
-identifier = cp_parser_identifier (parser);
+{
+  /* named-namespace-definition. */
+  identifier = cp_parser_identifier (parser);
+
+  while (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE)
+&& cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME)
+   {
+ /* nested-namespace-definition */
+ cp_lexer_consume_token (parser->lexer);
+ extra_identifiers.safe_insert (0, cp_parser_identifier (parser));
+   }
+}
   else
-identifier = NULL_TREE;
+{
+   /* unnamed-namespace-definition. */
+   identifier = NULL_TREE;
+}
+
+  if (!extra_identifie

PATCH for c++/64948

2015-02-13 Thread Andrea Azzarone
Hi all,

this patch try to fix PR c++/64948 (Lambda reference capture
initialization in template function creates segmentation fault).

2015-2-13 Andrea Azzarone 
  PR c++/64948
  * lambda.c (add_capture) Do not consider as rvalues all expressions
involving template parameters.


-- 
Andrea Azzarone
Index: gcc/cp/lambda.c
===
--- gcc/cp/lambda.c (revision 220454)
+++ gcc/cp/lambda.c (working copy)
@@ -506,7 +506,7 @@ add_capture (tree lambda, tree id, tree
   if (by_reference_p)
{
  type = build_reference_type (type);
- if (!real_lvalue_p (initializer))
+ if (TREE_TYPE (initializer) && !real_lvalue_p (initializer))
error ("cannot capture %qE by reference", initializer);
}
   else
Index: gcc/testsuite/g++.dg/cpp1y/lambda-init13.C
===
--- gcc/testsuite/g++.dg/cpp1y/lambda-init13.C  (revision 0)
+++ gcc/testsuite/g++.dg/cpp1y/lambda-init13.C  (working copy)
@@ -0,0 +1,10 @@
+// PR c++/64948
+// { dg-do compile { target c++14 } }
+
+template 
+void foo(T t) {
+  [&i = t.begin()]() {};
+}
+
+int main() {
+}
Index: gcc/testsuite/g++.dg/cpp1y/lambda-init14.C
===
--- gcc/testsuite/g++.dg/cpp1y/lambda-init14.C  (revision 0)
+++ gcc/testsuite/g++.dg/cpp1y/lambda-init14.C  (working copy)
@@ -0,0 +1,16 @@
+// PR c++/64948
+// { dg-do compile { target c++14 } }
+
+template 
+void foo(T t) {
+  [&i = t.begin()]() {};  // { dg-error "invalid initialization" }
+}
+
+struct X {
+  int begin() { return 0; }
+};
+
+int main() {
+  X x;
+  foo(x);
+}


Re: [PATCH] PR64959: SFINAE in UDLs

2015-02-13 Thread Andrea Azzarone
We can use the same trick used in the other tests. Patch attached.
Sorry about that!

2015-02-13 20:45 GMT+01:00 Jakub Jelinek :
> On Wed, Feb 11, 2015 at 12:26:33AM +0100, Andrea Azzarone wrote:
>> * 
>> gcc/testsuite/g++.dg/cpp1y/udlit-char-template-vs-std-literal-operator.C:
>
> This fails on i686-linux:
>
> FAIL: g++.dg/cpp1y/udlit-char-template-vs-std-literal-operator.C  -std=c++14 
> (test for excess errors)
> Excess errors: 
> /home/jakub/src/gcc/gcc/testsuite/g++.dg/cpp1y/udlit-char-template-vs-std-literal-operator.C:10:51:
>  error: 'int operator""_script(const char*, long unsigned int)' has invalid 
> argument list
>
> Perhaps you meant to #include  too and use
> size_t instead of unsigned long?  Or just __SIZE_TYPE__ instead
> of unsigned long?
>
> Jakub



-- 
Andrea Azzarone
http://launchpad.net/~andyrock
http://wiki.ubuntu.com/AndreaAzzarone
Index: gcc/testsuite/g++.dg/cpp1y/udlit-char-template-vs-std-literal-operator.C
===
--- gcc/testsuite/g++.dg/cpp1y/udlit-char-template-vs-std-literal-operator.C	(revision 220698)
+++ gcc/testsuite/g++.dg/cpp1y/udlit-char-template-vs-std-literal-operator.C	(working copy)
@@ -2,12 +2,14 @@
 
 #include 
 
+typedef decltype(sizeof(0)) size_type;
+
 template
 int operator"" _script () {
   return 1;
 }
 
-int operator"" _script (const char*, unsigned long) {
+int operator"" _script (const char*, size_type) {
   return 2;
 }
 


[PATCH][C++] PR 65071

2015-02-18 Thread Andrea Azzarone
Hi all,

this patch try to fix PR c++/65071 (ICE on valid, sizeof...() of
template template parameter pack in return type).

2015-2-18 Andrea Azzarone 
  PR c++/65071
  * gcc/cp/parser.c (cp_parser_sizeof_pack) Also consider template
template parameters.

Thanks.

-- 
Andrea Azzarone


Re: [PATCH][C++] PR 65071

2015-02-18 Thread Andrea Azzarone
Ops, forgot the diff.

2015-02-18 9:19 GMT+01:00 Andrea Azzarone :
> Hi all,
>
> this patch try to fix PR c++/65071 (ICE on valid, sizeof...() of
> template template parameter pack in return type).
>
> 2015-2-18 Andrea Azzarone 
>   PR c++/65071
>   * gcc/cp/parser.c (cp_parser_sizeof_pack) Also consider template
> template parameters.
>
> Thanks.
>
> --
> Andrea Azzarone



-- 
Andrea Azzarone
http://launchpad.net/~andyrock
http://wiki.ubuntu.com/AndreaAzzarone
Index: gcc/cp/parser.c
===
--- gcc/cp/parser.c	(revision 220698)
+++ gcc/cp/parser.c	(working copy)
@@ -24369,7 +24369,7 @@ cp_parser_sizeof_pack (cp_parser *parser
   if (expr == error_mark_node)
 cp_parser_name_lookup_error (parser, name, expr, NLE_NULL,
  token->location);
-  if (TREE_CODE (expr) == TYPE_DECL)
+  if (TREE_CODE (expr) == TYPE_DECL || TREE_CODE (expr) == TEMPLATE_DECL)
 expr = TREE_TYPE (expr);
   else if (TREE_CODE (expr) == CONST_DECL)
 expr = DECL_INITIAL (expr);
Index: gcc/testsuite/g++.dg/cpp0x/vt-65071.C
===
--- gcc/testsuite/g++.dg/cpp0x/vt-65071.C	(revision 0)
+++ gcc/testsuite/g++.dg/cpp0x/vt-65071.C	(working copy)
@@ -0,0 +1,9 @@
+// PR c++/65071
+// { dg-do compile { target c++11 } }
+
+template struct S {};
+
+template class... T, int N>
+S foo(T...);
+
+auto x = foo(S<2>{});



Re: PATCH for c++/64948

2015-02-19 Thread Andrea Azzarone
Ping?

2015-02-13 15:51 GMT+01:00 Andrea Azzarone :
> Hi all,
>
> this patch try to fix PR c++/64948 (Lambda reference capture
> initialization in template function creates segmentation fault).
>
> 2015-2-13 Andrea Azzarone 
>   PR c++/64948
>   * lambda.c (add_capture) Do not consider as rvalues all expressions
> involving template parameters.
>
>
> --
> Andrea Azzarone



-- 
Andrea Azzarone
http://launchpad.net/~andyrock
http://wiki.ubuntu.com/AndreaAzzarone


[PATCH][C++] Fix PR65091

2015-02-21 Thread Andrea Azzarone
Hi all,

please find attached a fix for pr 65071 "decltype(~arg) fails for
template functions". Basically we need to make sure that ~arg is
considered an expression and not a dtor.

2015-02-21 Andrea Azzarone 
  PR c++/65091
  * parser.c (cp_parser_decltype_expr): Make sure ~id is treated as an
expression.



-- 
Andrea Azzarone
Index: gcc/cp/parser.c
===
--- gcc/cp/parser.c	(revision 220698)
+++ gcc/cp/parser.c	(working copy)
@@ -12236,7 +12236,10 @@ cp_parser_decltype_expr (cp_parser *pars
   /*declarator_p=*/false,
   /*optional_p=*/false);
 
-  if (!cp_parser_error_occurred (parser) && expr != error_mark_node)
+  if (!cp_parser_error_occurred (parser)
+  && expr
+  && expr != error_mark_node
+  && (TREE_CODE (expr) != BIT_NOT_EXPR || TYPE_P (TREE_OPERAND (expr, 0
 {
   bool non_integral_constant_expression_p = false;
   tree id_expression = expr;
Index: gcc/testsuite/g++.dg/cpp0x/trailing10.C
===
--- gcc/testsuite/g++.dg/cpp0x/trailing10.C	(revision 0)
+++ gcc/testsuite/g++.dg/cpp0x/trailing10.C	(working copy)
@@ -0,0 +1,11 @@
+// PR c++/65091
+// { dg-do compile { target c++11 } }
+
+template
+auto foo(T x) -> decltype(~x) {
+  return ~x;
+}
+
+int bar() {
+  return foo(10);
+}