https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110347
--- Comment #2 from Tobias Burnus <burnus at gcc dot gnu.org> --- An explicit 'firstprivate(x)' will be turned in the compiler from a FIELD_DECL to: int D.2935 [value-expr: ((struct t *) this)->x]; #pragma omp target firstprivate(D.2934) firstprivate(D.2935) { (void) (D.2935 = 5) in semantics.cc's omp_privatize_field, called by finish_omp_clauses for handle_field_decl. The gimple dump then looks like: int x [value-expr: ((struct t *) this)->x]; #pragma omp target ... firstprivate(x) map(alloc:MEM[(char *)this] [len: 0]) map(firstprivate:this [pointer assign, bias: 0]) { this->x = 5; i.e. there is already a pointless 'this' mapping. For 'private', we could do in omp_privatize_field a simple: v = build_decl (input_location, VAR_DECL, DECL_NAME (t), TREE_TYPE (t)); but for 'firstprivate' that would miss the initialization - and adding a pointless assignment is not really the best, especially not for larger objects (like structs, arrays, reference types). * * * And for 'defaultmap(firstprivate)', the current code already adds 'this' mapping in the original dump: #pragma omp target map(tofrom:*(struct t *) this [len: 44]) map(firstprivate:(struct t *) this [pointer assign, bias: 0]) defaultmap(firstprivate:all) { { (void) (((struct t *) this)->x = 5); That's due to 'finish_omp_target_clauses_r' + data->this_expr_accessed = true; it either needs to be suppressed here - or later in the ME removed again. The former has the problem that 'defaultmap(firstprivate)' is not handled here, the latter means a special case - ensuring that it is only removed if all member accesses are for firstprivatized members. While 'private' does not exist as defaultmap, compiler-internal handling or (not checked) predefined/implicit mapping might.