*ping* [patch, fortran] Fix PR 85544

2018-12-22 Thread Thomas Koenig

Ping?


the PR pointed out an old regression because the front-end optimization
pass was substituting 2**n with ishift(1,n), where n was an array.

Simply removing the optimization for that case would have been easy,
but also introduced a performance regression.

So, for this, I moved the optimization to trans-*, where it makes more
sense.

Regression-tested.  This turned up that one of our tests, mvbits_1.f90,
depends on the behavior that 2**32 is zero.  This is certainly not
guaranteed by the standard, but I chose to keep the behavior as not
to introduce any changes in behavior.

This fixes a regression, so I would like to backport to all active
branches if this if possible.

Oh yes, if anybody feels strongly that we should also optimize 32**n
and powers of other powers to two, now is the time to speak up :-)

OK for affected branches?


Re: [PATCH] PR fortran/88169 -- remove error condition/message

2018-12-22 Thread Thomas Koenig

Hi Steve,


The attached patch addresses an issue submitted by Neil
Carlson.  He and I have an exchange in the PR's audit
trail hashing out the validity of his code example.  I
also asked on the J3 mailing about the his code.  It seems
that language of the Fortran standard may have been
misinterpreted when the gfortran code was committed.  See
the PR for more information.

The patch has been tested on x86_64-*-freebsd.  OK to commit?


OK.

Thanks for the patch!

Regards

Thomas


Re: [patch, fortran] Fix PR 85544

2018-12-22 Thread Paul Richard Thomas
Hi Thomas,

That's OK for 7-  through 9-branches.

Thanks for the fix.

Paul

On Sun, 16 Dec 2018 at 22:01, Thomas Koenig  wrote:
>
> Hello world,
>
> the PR pointed out an old regression because the front-end optimization
> pass was substituting 2**n with ishift(1,n), where n was an array.
>
> Simply removing the optimization for that case would have been easy,
> but also introduced a performance regression.
>
> So, for this, I moved the optimization to trans-*, where it makes more
> sense.
>
> Regression-tested.  This turned up that one of our tests, mvbits_1.f90,
> depends on the behavior that 2**32 is zero.  This is certainly not
> guaranteed by the standard, but I chose to keep the behavior as not
> to introduce any changes in behavior.
>
> This fixes a regression, so I would like to backport to all active
> branches if this if possible.
>
> Oh yes, if anybody feels strongly that we should also optimize 32**n
> and powers of other powers to two, now is the time to speak up :-)
>
> OK for affected branches?
>
> Regards
>
> Thomas
>
> 2018-12-16  Thomas Koenig  
>
>  PR fortran/85544
>  * frontend-passes.c (optimize_power): Remove.
>  (optimize_op): Remove call to optimize_power.
>  * trans-expr.c (gfc_conv_power_op): Handle cases of 1**integer,
>  (2|4|8|16) ** integer and (-1) ** integer.
>
> 2018-12-16  Thomas Koenig  
>
>  PR fortran/85544
>  * gfortran.dg/power_7.f90: New test.



-- 
"If you can't explain it simply, you don't understand it well enough"
- Albert Einstein


Re: [patch,openacc] Fix PR71959: lto dump of callee counts

2018-12-22 Thread Iain Sandoe
Hi Julian,

> On 21 Dec 2018, at 16:47, Julian Brown  wrote:
> 

> On Fri, 21 Dec 2018 14:31:19 +0100
> Jakub Jelinek  wrote:
> 
>> On Fri, Dec 21, 2018 at 01:23:03PM +, Julian Brown wrote:
>>> 2018-xx-yy  Nathan Sidwell  
> 

>>> * testsuite/libgomp.oacc-c++/pr71959-a.C: New.
>>> * testsuite/libgomp.oacc-c++/pr71959.C: New.  
>> 
>>> +void apply (int (*fn)(), Iter out) asm
>>> ("_ZN5Apply5applyEPFivE4Iter");  
>> 
>> Will this work even on targets that use _ or other symbol prefixes?
> 
> I'd guess so, else there would be no portable way of using "asm" to
> write pre-mangled C++ names. The only existing similar uses I could find
> in the testsuite are for the ifunc attribute, not asm, though (e.g.
> g++.dg/ext/attr-ifunc-*.C).

It won’t work on such targets (e.g. Darwin)
… but it’s not too hard to make it happen (see, for example, gcc.dg/memcmp-1.c)

One just has to remember that __USER_LABEL_PREFIX__ is a token, not a string.

so .. in the example above…

#define STR1(X) #X
#define STR2(X) STR1(X)

….

 asm(STR2(__USER_LABEL_PREFIX__) "_ZN5Apply5applyEPFivE4Iter”);

> Anyway, OpenACC is only useful for a handful of targets at present,
> neither of which use special symbol prefixes AFAIK.

I have hopes of one day getting offloading to work on Darwin (the only 
limitation is developer time,
not technical feasibility) .. 

cheers
Iain



Re: [PATCH, C++] Fix PR c++/88261

2018-12-22 Thread Bernd Edlinger
On 12/21/18 2:03 AM, Martin Sebor wrote:
> On 12/20/18 2:07 PM, Bernd Edlinger wrote:
>> On 12/20/18 6:50 PM, Martin Sebor wrote:
>>> On 12/20/18 10:46 AM, Martin Sebor wrote:
 On 12/17/18 7:58 AM, Jason Merrill wrote:
> On 12/15/18 3:36 AM, Bernd Edlinger wrote:
>> this patch implements an error message, for non-static initialization of 
>> a flexible array member.
>> This duplicates the existing error message from the C-FE, to avoid ICE 
>> and wrong code generation
>> issues, as pointed out in the PR.
>>
>> It is a bit funny that a non-functional feature like that has already 
>> rather much test coverage.
>> The most easy adjustment seems to change the existing test cases to use 
>> static declarations.
>
> Martin, thoughts?

 Our high-level goal when tightening up how flexible array members
 are handled in C++ was to accept what's accepted in standard C mode
 and reject (or, at a minimum, warn for) C++ extensions that could
 be relied on in existing code.
>>>
>>> I meant "reject what couldn't be relied on" and "warn for that could
>>> be."
>>>
>>
>> I believe the problem here is effectively that initializing non-static
>> flexible array is not supported by the middle-end.  All examples
>> where flexible array members are initialized on automatic variable
>> work only as long as they are simple enough that they are optimized
>> away so that they do not survive until expansion.
>>
>> Take as example gcc/testsuite/g++.dg/ext/flexary13.C,
>> it compiles and runs successfully, but the assertions start to
>> fail if Ax is declared volatile, and at the same time, we know
>> that the automatic variables are allocated in a way that they
>> can overlap and crash at any time.
>>
>> My impression is that the existing C error made the middle-end kind of rely
>> on this behavior.
>>
>> So I think the right thing to do is duplicate the existing C error in
>> the C++ FE.  I do not see any automatic variable with initialized flexible
>> data members where it would be safe to only warn about them.
> 
> If there are no reasonable use cases that code out there could
> be relying on because none of them works correctly then rejecting
> the initialization makes sense to me.
> 
>>> (Sorry for the delay, by the way.  I've been migrating to a new machine
>>> this week and things aren't yet working quite like I'm used to.)
>>>

 The flexarray tests I added back then were for features that looked
 like intentional extensions and that seemed to work for at least
 some use cases as far as I could tell.  What I noticed didn't work
 I created bugs for: 69338, 69696, and 69338 look related, but there
 are others.

 I think all these bugs should all be reviewed and a decision made
 about what's intended to work and what continues to be accepted as
 an accident and should be rejected.  After that, we can adjust
 the existing tests.

>>
>> I would not rule out the possibility that there can be more bugs.
>> But I think the existing tests need to avoid the case which evokes
>> the new error.  The question is, if changing from automatic to static
>> objects prevents those tests to test what they were originally written for.
>> I believe this is not the case, but I do probably not know all the
>> background here.
> 
> IIRC, most of the tests I added were meant to exercise just
> the front-end, not any later stages (if that's what you meant).
> Otherwise, if you're worried about the changes from auto to
> static no longer exercising downstream front-end code, whether
> that matters depends on the intent of each test.
> 
> flexary13.C was most likely meant to also verify codegen (hence
> the assertions) so I would suggest to make it do that (i.e.,
> verify the assertions are optimized out if in fact they are,
> or make the test run so they must pass).
> 

Oh well, unfortunately the modified test case with static objects
fails one assertion when executed at -O0, I missed that before,
because I used -O2 or higher.  I filed that as PR 88578, so in the
moment I would like to leave the test case as compile only,
and change that to run once PR 88578 is resolved.

> The changes to the rest of the flexary*.C tests seem okay,
> though a new test should be added to explicitly exercise this
> change (bug 88261), even if the error happens to be tested by
> one of the changed tests.
> 

That is the case, because the array-6.c test case was moved
to c-c++-common.  That is the reproducer for the ICE from the PR.

> In changes to the Wplacement-new-size*.C tests I would suggest
> to follow the same approach of using statics instead of testing
> for errors so the code that exercises warnings doesn't depend
> on erroneous constructs.
> 
> The comment in Wplacement-new-size-2.C just above the code your
> patch changes that reads:
> 
>    // Initialization of non-static objects with flexible array members
>    // isn't allowed in C and sh

Re: [PATCH] PR fortran/85798 -- Check for allocatable components in data statement

2018-12-22 Thread Steve Kargl
On Thu, Dec 20, 2018 at 05:00:19PM -0800, Steve Kargl wrote:
> On Sun, Dec 16, 2018 at 11:04:44AM -0800, Steve Kargl wrote:
> > The attached patch has been tested on i586-*-freebsd and x86_64-*-freebsd.
> > If a data-statement-object is a component of a derived type, it checks if
> > that component is allocatable.
> > 
> > 2018-12-16  Steven G . Kargl  
> > 
> > PR fortran/85798
> > * decl.c (gfc_match_data): If a component of a derived type entity
> > appears in data statement, check that does not have the allocatable
> > attribute.
> >  
> > 2018-12-16  Steven G . Kargl  
> > 
> > PR fortran/85798
> > * gfortran.dg/pr85798.f90: New test.
> > 
> 
> Ping.
> 

Committed.

-- 
Steve


Fix devirtualization with LTO

2018-12-22 Thread Jan Hubicka
Hi,
while fixing Firefox issues I also noticed that type simplification
completely disabled type based devirtualization on LTO path. Problem
is that method pointers now point to simplified type and 
obj_type_ref_class is not ready for that.

I also moved testcases where it makes sense to lto so this does not
happen again. This is not trivial task since one needs to work out why
testcases behaves differently when they do, so I will follow up on this
and convert more.

Bootstrapped/regtested x86_64-linux, comitted.

Honza

* tree.c: (obj_type_ref_class): Move to...
* ipa-devirt.c (obj_type_ref_class): Move to here; lookup main
odr type.
(get_odr_type): Compensate for type simplification.

* g++.dg/ipa/devirt-30.C: Add dg-do.
* g++.dg/lto/devirt-1_0.C: New testcase.
* g++.dg/lto/devirt-2_0.C: New testcase.
* g++.dg/lto/devirt-3_0.C: New testcase.
* g++.dg/lto/devirt-4_0.C: New testcase.
* g++.dg/lto/devirt-5_0.C: New testcase.
* g++.dg/lto/devirt-6_0.C: New testcase.
* g++.dg/lto/devirt-13_0.C: New testcase.
* g++.dg/lto/devirt-14_0.C: New testcase.
* g++.dg/lto/devirt-19_0.C: New testcase.
* g++.dg/lto/devirt-22_0.C: New testcase.
* g++.dg/lto/devirt-23_0.C: New testcase.
* g++.dg/lto/devirt-30_0.C: New testcase.
* g++.dg/lto/devirt-34_0.C: New testcase.

Index: ipa-devirt.c
===
--- ipa-devirt.c(revision 267337)
+++ ipa-devirt.c(working copy)
@@ -1985,6 +1985,30 @@ add_type_duplicate (odr_type val, tree t
   return build_bases;
 }
 
+/* REF is OBJ_TYPE_REF, return the class the ref corresponds to.  */
+
+tree
+obj_type_ref_class (const_tree ref)
+{
+  gcc_checking_assert (TREE_CODE (ref) == OBJ_TYPE_REF);
+  ref = TREE_TYPE (ref);
+  gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE);
+  ref = TREE_TYPE (ref);
+  /* We look for type THIS points to.  ObjC also builds
+ OBJ_TYPE_REF with non-method calls, Their first parameter
+ ID however also corresponds to class type. */
+  gcc_checking_assert (TREE_CODE (ref) == METHOD_TYPE
+  || TREE_CODE (ref) == FUNCTION_TYPE);
+  ref = TREE_VALUE (TYPE_ARG_TYPES (ref));
+  gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE);
+  tree ret = TREE_TYPE (ref);
+  if (!in_lto_p)
+ret = TYPE_CANONICAL (ret);
+  else
+ret = get_odr_type (ret)->type;
+  return ret;
+}
+
 /* Get ODR type hash entry for TYPE.  If INSERT is true, create
possibly new entry.  */
 
@@ -2000,6 +2024,8 @@ get_odr_type (tree type, bool insert)
   int base_id = -1;
 
   type = TYPE_MAIN_VARIANT (type);
+  if (!in_lto_p)
+type = TYPE_CANONICAL (type);
 
   gcc_checking_assert (can_be_name_hashed_p (type)
   || can_be_vtable_hashed_p (type));
Index: testsuite/g++.dg/ipa/devirt-30.C
===
--- testsuite/g++.dg/ipa/devirt-30.C(revision 267337)
+++ testsuite/g++.dg/ipa/devirt-30.C(working copy)
@@ -1,4 +1,5 @@
 // PR c++/58678
+// { dg-do compile }
 // { dg-options "-O3 -fdump-ipa-devirt" }
 
 // We shouldn't speculatively devirtualize to ~B because B is an abstract
Index: testsuite/g++.dg/lto/devirt-13_0.C
===
--- testsuite/g++.dg/lto/devirt-13_0.C  (nonexistent)
+++ testsuite/g++.dg/lto/devirt-13_0.C  (working copy)
@@ -0,0 +1,5 @@
+/* { dg-lto-do run } */
+/* Call to foo should be devirtualized because there are no derived types of 
A.  */
+/* { dg-lto-options "-O2 -flto -fdump-tree-ssa"  } */
+#include "../ipa/devirt-13.C"
+/* { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 0 "ssa"} } */
Index: testsuite/g++.dg/lto/devirt-14_0.C
===
--- testsuite/g++.dg/lto/devirt-14_0.C  (nonexistent)
+++ testsuite/g++.dg/lto/devirt-14_0.C  (working copy)
@@ -0,0 +1,4 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options "-O2 -fdump-tree-ssa"  } */
+#include "../ipa/devirt-14.C"
+/* { dg-final { scan-tree-dump-not "A.*foo" "ssa"} } */
Index: testsuite/g++.dg/lto/devirt-19_0.C
===
--- testsuite/g++.dg/lto/devirt-19_0.C  (nonexistent)
+++ testsuite/g++.dg/lto/devirt-19_0.C  (working copy)
@@ -0,0 +1,5 @@
+/* { dg-lto-do link } */
+/* { dg-lto-options { "-O2 -fdump-ipa-cp -Wno-return-type -flto -r -nostdlib" 
} } */
+/* { dg-extra-ld-options "-flinker-output=nolto-rel" } */
+#include "../ipa/devirt-19.C"
+/* { dg-final { scan-wpa-ipa-dump-times "Discovered a virtual call to a known 
target" 1 "cp"  } } */
Index: testsuite/g++.dg/lto/devirt-1_0.C
===
--- testsuite/g++.dg/lto/devirt-1_0.C   (nonexistent)
+++ testsuite/g++.dg/lto/devirt-1_0.C   (working copy)
@@ -0,0 +1,4 @@
+/* { dg-lto-do run } */
+/* { dg-lto-opti

Re: [PATCH, OpenACC] Enable GOMP_MAP_FIRSTPRIVATE_INT for OpenACC

2018-12-22 Thread Julian Brown
On Tue, 18 Dec 2018 13:47:34 +0100
Jakub Jelinek  wrote:

> On Thu, Dec 13, 2018 at 03:44:25PM +, Julian Brown wrote:
> > +static tree
> > +convert_to_firstprivate_int (tree var, gimple_seq *gs)
> > +{
> > +  tree type = TREE_TYPE (var), new_type = NULL_TREE;
> > +  tree tmp = NULL_TREE;
> > +
> > +  if (omp_is_reference (var))
> > +type = TREE_TYPE (type);
> > +
> > +  if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
> > +{
> > +  if (omp_is_reference (var))
> > +   {
> > + tmp = create_tmp_var (type);
> > + gimplify_assign (tmp, build_simple_mem_ref (var), gs);
> > + var = tmp;
> > +   }
> > +
> > +  return fold_convert (pointer_sized_int_node, var);
> > +}
> > +
> > +  gcc_assert (tree_to_uhwi (TYPE_SIZE (type)) <= POINTER_SIZE);
> > +
> > +  new_type = lang_hooks.types.type_for_size (tree_to_uhwi
> > (TYPE_SIZE (type)),
> > +true);
> > +
> > +  if (omp_is_reference (var))
> > +{
> > +  tmp = create_tmp_var (type);
> > +  gimplify_assign (tmp, build_simple_mem_ref (var), gs);
> > +  var = tmp;
> > +}  
> 
> Why are you duplicating this if?  Can't you just do it before the
>   if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
> test once, even better in the same if as you do type = TREE_TYPE
> (type); ?
> 
> Otherwise ok from me, but please check with Thomas if he is ok with
> it too.

Thanks! This version tidies up the code duplication. Re-tested with
offloading to nvptx.

Thomas - OK with you?

Julian
commit 5861e3529ed799715bbd2ea40d5b08a9ddae49bb
Author: Julian Brown 
Date:   Thu Dec 6 04:38:59 2018 -0800

Enable GOMP_MAP_FIRSTPRIVATE_INT for OpenACC

	gcc/
	* omp-low.c (maybe_lookup_field_in_outer_ctx): New function.
	(convert_to_firstprivate_int): New function.
	(convert_from_firstprivate_int): New function.
	(lower_omp_target): Enable GOMP_MAP_FIRSTPRIVATE_INT in OpenACC.

	libgomp/
	* oacc-parallel.c (GOACC_parallel_keyed): Handle
	GOMP_MAP_FIRSTPRIVATE_INT host addresses.
	* plugin/plugin-nvptx.c (nvptx_exec): Handle GOMP_MAP_FIRSTPRIVATE_INT
	host addresses.
	* testsuite/libgomp.oacc-c++/firstprivate-int.C: New test.
	* testsuite/libgomp.oacc-c-c++-common/firstprivate-int.c: New test.
	* testsuite/libgomp.oacc-fortran/firstprivate-int.f90: New test.

diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index b406ce7..1fc2538 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -3497,6 +3497,19 @@ maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
   return t ? t : decl;
 }
 
+/* Returns true if DECL is present inside a field that encloses CTX.  */
+
+static bool
+maybe_lookup_field_in_outer_ctx (tree decl, omp_context *ctx)
+{
+  omp_context *up;
+
+  for (up = ctx->outer; up; up = up->outer)
+if (maybe_lookup_field (decl, up))
+  return true;
+
+  return false;
+}
 
 /* Construct the initialization value for reduction operation OP.  */
 
@@ -9052,6 +9065,74 @@ lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 }
 }
 
+/* Helper function for lower_omp_target.  Converts VAR to something that can
+   be represented by a POINTER_SIZED_INT_NODE.  Any new instructions are
+   appended to GS.  This is used to optimize firstprivate variables, so that
+   small types (less precision than POINTER_SIZE) do not require additional
+   data mappings.  */
+
+static tree
+convert_to_firstprivate_int (tree var, gimple_seq *gs)
+{
+  tree type = TREE_TYPE (var), new_type = NULL_TREE;
+
+  if (omp_is_reference (var))
+{
+  type = TREE_TYPE (type);
+  tree tmp = create_tmp_var (type);
+  gimplify_assign (tmp, build_simple_mem_ref (var), gs);
+  var = tmp;
+}
+
+  if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
+return fold_convert (pointer_sized_int_node, var);
+
+  gcc_assert (tree_to_uhwi (TYPE_SIZE (type)) <= POINTER_SIZE);
+
+  new_type = lang_hooks.types.type_for_size (tree_to_uhwi (TYPE_SIZE (type)),
+	 true);
+  tree tmp = create_tmp_var (new_type);
+  var = fold_build1 (VIEW_CONVERT_EXPR, new_type, var);
+  gimplify_assign (tmp, var, gs);
+
+  return fold_convert (pointer_sized_int_node, tmp);
+}
+
+/* Like convert_to_firstprivate_int, but restore the original type.  */
+
+static tree
+convert_from_firstprivate_int (tree var, bool is_ref, gimple_seq *gs)
+{
+  tree type = TREE_TYPE (var);
+  tree new_type = NULL_TREE;
+  tree tmp = NULL_TREE;
+
+  gcc_assert (TREE_CODE (var) == MEM_REF);
+  var = TREE_OPERAND (var, 0);
+
+  if (INTEGRAL_TYPE_P (var) || POINTER_TYPE_P (type))
+return fold_convert (type, var);
+
+  gcc_assert (tree_to_uhwi (TYPE_SIZE (type)) <= POINTER_SIZE);
+
+  new_type = lang_hooks.types.type_for_size (tree_to_uhwi (TYPE_SIZE (type)),
+	 true);
+
+  tmp = create_tmp_var (new_type);
+  var = fold_convert (new_type, var);
+  gimplify_assign (tmp, var, gs);
+  var = fold_build1 (VIEW_CONVERT_EXPR, 

C++ PATCH for c++/88548, this accepted in static member functions

2018-12-22 Thread Marek Polacek
I noticed that we weren't diagnosing using 'this' in noexcept-specifiers
of static member functions, and Jakub pointed out that this is also true
for trailing-return-type.  cp_parser has local_variables_forbidden_p to
detect using local vars and 'this' in certain contexts, so let's use that.

...except that I found out that I need to be able to distinguish between
forbidding just local vars and/or this, so I've changed its type to char.
For instance, you can't use 'this' in a static member function declaration,
but you can use a local var because noexcept/decltype is an unevaluated
context.

I also noticed that we weren't diagnosing 'this' in a friend declaration,
which is also forbidden.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2018-12-22  Marek Polacek  

PR c++/88548 - this accepted in static member functions.
* parser.c (cp_debug_parser): Adjust printing of
local_variables_forbidden_p.
(cp_parser_new): Set local_variables_forbidden_p to 0 rather than false.
(cp_parser_primary_expression): When checking
local_variables_forbidden_p, use THIS_FORBIDDEN or
LOCAL_VARS_FORBIDDEN.
(cp_parser_lambda_body): Update the type of
local_variables_forbidden_p.  Set it to 0 rather than false.
(cp_parser_condition): Adjust call to cp_parser_declarator.
(cp_parser_explicit_instantiation): Likewise.
(cp_parser_init_declarator): Likewise.
(cp_parser_declarator): New parameter.  Use it.
(cp_parser_direct_declarator): New parameter.  Use it to set
local_variables_forbidden_p.  Adjust call to cp_parser_declarator.
(cp_parser_type_id_1): Adjust call to cp_parser_declarator.
(cp_parser_parameter_declaration): Likewise.
(cp_parser_default_argument): Update the type of
local_variables_forbidden_p.  Set it to LOCAL_VARS_AND_THIS_FORBIDDEN
rather than true.
(cp_parser_member_declaration): Tell cp_parser_declarator if we saw
'static' or 'friend'.
(cp_parser_exception_declaration): Adjust call to cp_parser_declarator.
(cp_parser_late_parsing_default_args): Update the type of
local_variables_forbidden_p.  Set it to LOCAL_VARS_AND_THIS_FORBIDDEN
rather than true.
(cp_parser_cache_defarg): Adjust call to cp_parser_declarator.
(cp_parser_objc_class_ivars): Likewise.
(cp_parser_objc_struct_declaration): Likewise.
(cp_parser_omp_for_loop_init): Likewise.
* parser.h (cp_parser): Change the type of local_variables_forbidden_p
to unsigned char.
(LOCAL_VARS_FORBIDDEN, LOCAL_VARS_AND_THIS_FORBIDDEN, THIS_FORBIDDEN):
Define.

* g++.dg/cpp0x/this1.C: New test.

diff --git gcc/cp/parser.c gcc/cp/parser.c
index 2cd91a37031..8aab21f3d33 100644
--- gcc/cp/parser.c
+++ gcc/cp/parser.c
@@ -536,9 +536,12 @@ cp_debug_parser (FILE *file, cp_parser *parser)
  parser->allow_non_integral_constant_expression_p);
   cp_debug_print_flag (file, "Seen non-constant expression",
  parser->non_integral_constant_expression_p);
-  cp_debug_print_flag (file, "Local names and 'this' forbidden in "
- "current context",
- parser->local_variables_forbidden_p);
+  cp_debug_print_flag (file, "Local names forbidden in current context",
+ (parser->local_variables_forbidden_p
+  & LOCAL_VARS_FORBIDDEN));
+  cp_debug_print_flag (file, "'this' forbidden in current context",
+ (parser->local_variables_forbidden_p
+  & THIS_FORBIDDEN));
   cp_debug_print_flag (file, "In unbraced linkage specification",
  parser->in_unbraced_linkage_specification_p);
   cp_debug_print_flag (file, "Parsing a declarator",
@@ -2203,9 +2206,10 @@ static tree cp_parser_init_declarator
location_t *, tree *);
 static cp_declarator *cp_parser_declarator
   (cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool *,
-   bool, bool);
+   bool, bool, bool);
 static cp_declarator *cp_parser_direct_declarator
-  (cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool, bool);
+  (cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool, bool,
+   bool);
 static enum tree_code cp_parser_ptr_operator
   (cp_parser *, tree *, cp_cv_quals *, tree *);
 static cp_cv_quals cp_parser_cv_qualifier_seq_opt
@@ -3951,7 +3955,7 @@ cp_parser_new (void)
   parser->non_integral_constant_expression_p = false;
 
   /* Local variable names are not forbidden.  */
-  parser->local_variables_forbidden_p = false;
+  parser->local_variables_forbidden_p = 0;
 
   /* We are not processing an `extern "C"' declaration.  */
   parser->in_unbraced_linkage_specification_p = false;
@@ -5405,7 +5409,7 @@ cp_parser_primary_expression (cp_parser *parser,
  /*