xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/cp/friend.c (revision 23f5f46327e37e7811da3520f4bb933f9489322f)
1 /* Help friends in C++.
2    Copyright (C) 1997-2020 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10 
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19 
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "cp-tree.h"
24 
25 /* Friend data structures are described in cp-tree.h.  */
26 
27 
28 /* The GLOBAL_FRIEND scope (functions, classes, or templates) is
29    regarded as a friend of every class.  This is only used by libcc1,
30    to enable GDB's code snippets to access private members without
31    disabling access control in general, which could cause different
32    template overload resolution results when accessibility matters
33    (e.g. tests for an accessible member).  */
34 
35 static GTY(()) tree global_friend;
36 
37 /* Set the GLOBAL_FRIEND for this compilation session.  It might be
38    set multiple times, but always to the same scope.  */
39 
40 void
set_global_friend(tree scope)41 set_global_friend (tree scope)
42 {
43   gcc_checking_assert (scope != NULL_TREE);
44   gcc_assert (!global_friend || global_friend == scope);
45   global_friend = scope;
46 }
47 
48 /* Return TRUE if SCOPE is the global friend.  */
49 
50 bool
is_global_friend(tree scope)51 is_global_friend (tree scope)
52 {
53   gcc_checking_assert (scope != NULL_TREE);
54 
55   if (global_friend == scope)
56     return true;
57 
58   if (!global_friend)
59     return false;
60 
61   if (is_specialization_of_friend (global_friend, scope))
62     return true;
63 
64   return false;
65 }
66 
67 /* Returns nonzero if SUPPLICANT is a friend of TYPE.  */
68 
69 int
is_friend(tree type,tree supplicant)70 is_friend (tree type, tree supplicant)
71 {
72   int declp;
73   tree list;
74   tree context;
75 
76   if (supplicant == NULL_TREE || type == NULL_TREE)
77     return 0;
78 
79   if (is_global_friend (supplicant))
80     return 1;
81 
82   declp = DECL_P (supplicant);
83 
84   if (declp)
85     /* It's a function decl.  */
86     {
87       tree list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type));
88       tree name = DECL_NAME (supplicant);
89 
90       for (; list ; list = TREE_CHAIN (list))
91 	{
92 	  if (name == FRIEND_NAME (list))
93 	    {
94 	      tree friends = FRIEND_DECLS (list);
95 	      for (; friends ; friends = TREE_CHAIN (friends))
96 		{
97 		  tree this_friend = TREE_VALUE (friends);
98 
99 		  if (this_friend == NULL_TREE)
100 		    continue;
101 
102 		  if (supplicant == this_friend)
103 		    return 1;
104 
105 		  if (is_specialization_of_friend (supplicant, this_friend))
106 		    return 1;
107 		}
108 	      break;
109 	    }
110 	}
111     }
112   else
113     /* It's a type.  */
114     {
115       if (same_type_p (supplicant, type))
116 	return 1;
117 
118       list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type)));
119       for (; list ; list = TREE_CHAIN (list))
120 	{
121 	  tree t = TREE_VALUE (list);
122 
123 	  if (TREE_CODE (t) == TEMPLATE_DECL ?
124 	      is_specialization_of_friend (TYPE_MAIN_DECL (supplicant), t) :
125 	      same_type_p (supplicant, t))
126 	    return 1;
127 	}
128     }
129 
130   if (declp)
131     {
132       if (DECL_FUNCTION_MEMBER_P (supplicant))
133 	context = DECL_CONTEXT (supplicant);
134       else
135 	context = NULL_TREE;
136     }
137   else
138     {
139       if (TYPE_CLASS_SCOPE_P (supplicant))
140 	/* Nested classes get the same access as their enclosing types, as
141 	   per DR 45 (this is a change from the standard).  */
142 	context = TYPE_CONTEXT (supplicant);
143       else
144 	/* Local classes have the same access as the enclosing function.  */
145 	context = decl_function_context (TYPE_MAIN_DECL (supplicant));
146     }
147 
148   /* A namespace is not friend to anybody.  */
149   if (context && TREE_CODE (context) == NAMESPACE_DECL)
150     context = NULL_TREE;
151 
152   if (context)
153     return is_friend (type, context);
154 
155   return 0;
156 }
157 
158 /* Add a new friend to the friends of the aggregate type TYPE.
159    DECL is the FUNCTION_DECL of the friend being added.
160 
161    If COMPLAIN is true, warning about duplicate friend is issued.
162    We want to have this diagnostics during parsing but not
163    when a template is being instantiated.  */
164 
165 void
add_friend(tree type,tree decl,bool complain)166 add_friend (tree type, tree decl, bool complain)
167 {
168   tree typedecl;
169   tree list;
170   tree name;
171   tree ctx;
172 
173   if (decl == error_mark_node)
174     return;
175 
176   typedecl = TYPE_MAIN_DECL (type);
177   list = DECL_FRIENDLIST (typedecl);
178   name = DECL_NAME (decl);
179   type = TREE_TYPE (typedecl);
180 
181   while (list)
182     {
183       if (name == FRIEND_NAME (list))
184 	{
185 	  tree friends = FRIEND_DECLS (list);
186 	  for (; friends ; friends = TREE_CHAIN (friends))
187 	    {
188 	      if (decl == TREE_VALUE (friends))
189 		{
190 		  if (complain)
191 		    warning (OPT_Wredundant_decls,
192 			     "%qD is already a friend of class %qT",
193 			     decl, type);
194 		  return;
195 		}
196 	    }
197 
198 	  TREE_VALUE (list) = tree_cons (NULL_TREE, decl,
199 					 TREE_VALUE (list));
200 	  break;
201 	}
202       list = TREE_CHAIN (list);
203     }
204 
205   ctx = DECL_CONTEXT (decl);
206   if (ctx && CLASS_TYPE_P (ctx) && !uses_template_parms (ctx))
207     perform_or_defer_access_check (TYPE_BINFO (ctx), decl, decl,
208 				   tf_warning_or_error);
209 
210   maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);
211 
212   if (!list)
213     DECL_FRIENDLIST (typedecl)
214       = tree_cons (DECL_NAME (decl), build_tree_list (NULL_TREE, decl),
215 		   DECL_FRIENDLIST (typedecl));
216   if (!uses_template_parms (type))
217     DECL_BEFRIENDING_CLASSES (decl)
218       = tree_cons (NULL_TREE, type,
219 		   DECL_BEFRIENDING_CLASSES (decl));
220 }
221 
222 /* Make FRIEND_TYPE a friend class to TYPE.  If FRIEND_TYPE has already
223    been defined, we make all of its member functions friends of
224    TYPE.  If not, we make it a pending friend, which can later be added
225    when its definition is seen.  If a type is defined, then its TYPE_DECL's
226    DECL_UNDEFINED_FRIENDS contains a (possibly empty) list of friend
227    classes that are not defined.  If a type has not yet been defined,
228    then the DECL_WAITING_FRIENDS contains a list of types
229    waiting to make it their friend.  Note that these two can both
230    be in use at the same time!
231 
232    If COMPLAIN is true, warning about duplicate friend is issued.
233    We want to have this diagnostics during parsing but not
234    when a template is being instantiated.  */
235 
236 void
make_friend_class(tree type,tree friend_type,bool complain)237 make_friend_class (tree type, tree friend_type, bool complain)
238 {
239   tree classes;
240 
241   /* CLASS_TEMPLATE_DEPTH counts the number of template headers for
242      the enclosing class.  FRIEND_DEPTH counts the number of template
243      headers used for this friend declaration.  TEMPLATE_MEMBER_P,
244      defined inside the `if' block for TYPENAME_TYPE case, is true if
245      a template header in FRIEND_DEPTH is intended for DECLARATOR.
246      For example, the code
247 
248        template <class T> struct A {
249 	 template <class U> struct B {
250 	   template <class V> template <class W>
251 	     friend class C<V>::D;
252 	 };
253        };
254 
255      will eventually give the following results
256 
257      1. CLASS_TEMPLATE_DEPTH equals 2 (for `T' and `U').
258      2. FRIEND_DEPTH equals 2 (for `V' and `W').
259      3. TEMPLATE_MEMBER_P is true (for `W').
260 
261      The friend is a template friend iff FRIEND_DEPTH is nonzero.  */
262 
263   int class_template_depth = template_class_depth (type);
264   int friend_depth = processing_template_decl - class_template_depth;
265 
266   if (! MAYBE_CLASS_TYPE_P (friend_type)
267       && TREE_CODE (friend_type) != TEMPLATE_TEMPLATE_PARM)
268     {
269       /* N1791: If the type specifier in a friend declaration designates a
270 	 (possibly cv-qualified) class type, that class is declared as a
271 	 friend; otherwise, the friend declaration is ignored.
272 
273          So don't complain in C++11 mode.  */
274       if (cxx_dialect < cxx11)
275 	pedwarn (input_location, complain ? 0 : OPT_Wpedantic,
276 		 "invalid type %qT declared %<friend%>", friend_type);
277       return;
278     }
279 
280   friend_type = cv_unqualified (friend_type);
281 
282   if (check_for_bare_parameter_packs (friend_type))
283     return;
284 
285   if (friend_depth)
286     {
287       /* [temp.friend] Friend declarations shall not declare partial
288 	 specializations.  */
289       if (CLASS_TYPE_P (friend_type)
290 	  && CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type)
291 	  && uses_template_parms (friend_type))
292 	{
293 	  error ("partial specialization %qT declared %<friend%>",
294 		 friend_type);
295 	  return;
296 	}
297 
298       if (TYPE_TEMPLATE_INFO (friend_type)
299 	  && !PRIMARY_TEMPLATE_P (TYPE_TI_TEMPLATE (friend_type)))
300 	{
301 	  auto_diagnostic_group d;
302 	  error ("%qT is not a template", friend_type);
303 	  inform (location_of (friend_type), "previous declaration here");
304 	  if (TYPE_CLASS_SCOPE_P (friend_type)
305 	      && CLASSTYPE_TEMPLATE_INFO (TYPE_CONTEXT (friend_type))
306 	      && currently_open_class (TYPE_CONTEXT (friend_type)))
307 	    inform (input_location, "perhaps you need explicit template "
308 		    "arguments in your nested-name-specifier");
309 	  return;
310 	}
311     }
312 
313   /* It makes sense for a template class to be friends with itself,
314      that means the instantiations can be friendly.  Other cases are
315      not so meaningful.  */
316   if (!friend_depth && same_type_p (type, friend_type))
317     {
318       if (complain)
319 	warning (0, "class %qT is implicitly friends with itself",
320 		 type);
321       return;
322     }
323 
324   /* [temp.friend]
325 
326      A friend of a class or class template can be a function or
327      class template, a specialization of a function template or
328      class template, or an ordinary (nontemplate) function or
329      class.  */
330   if (!friend_depth)
331     ;/* ok */
332   else if (TREE_CODE (friend_type) == TYPENAME_TYPE)
333     {
334       if (TREE_CODE (TYPENAME_TYPE_FULLNAME (friend_type))
335 	  == TEMPLATE_ID_EXPR)
336 	{
337 	  /* template <class U> friend class T::X<U>; */
338 	  /* [temp.friend]
339 	     Friend declarations shall not declare partial
340 	     specializations.  */
341 	  error ("partial specialization %qT declared %<friend%>",
342 		 friend_type);
343 	  return;
344 	}
345       else
346 	{
347 	  /* We will figure this out later.  */
348 	  bool template_member_p = false;
349 
350 	  tree ctype = TYPE_CONTEXT (friend_type);
351 	  tree name = TYPE_IDENTIFIER (friend_type);
352 	  tree decl;
353 
354 	  if (!uses_template_parms_level (ctype, class_template_depth
355 						 + friend_depth))
356 	    template_member_p = true;
357 
358 	  if (class_template_depth)
359 	    {
360 	      /* We rely on tsubst_friend_class to check the
361 		 validity of the declaration later.  */
362 	      if (template_member_p)
363 		friend_type
364 		  = make_unbound_class_template (ctype,
365 						 name,
366 						 current_template_parms,
367 						 tf_error);
368 	      else
369 		friend_type
370 		  = make_typename_type (ctype, name, class_type, tf_error);
371 	    }
372 	  else
373 	    {
374 	      decl = lookup_member (ctype, name, 0, true, tf_warning_or_error);
375 	      if (!decl)
376 		{
377 		  error ("%qT is not a member of %qT", name, ctype);
378 		  return;
379 		}
380 	      if (template_member_p && !DECL_CLASS_TEMPLATE_P (decl))
381 		{
382 		  auto_diagnostic_group d;
383 		  error ("%qT is not a member class template of %qT",
384 			 name, ctype);
385 		  inform (DECL_SOURCE_LOCATION (decl),
386 			  "%qD declared here", decl);
387 		  return;
388 		}
389 	      if (!template_member_p && (TREE_CODE (decl) != TYPE_DECL
390 					 || !CLASS_TYPE_P (TREE_TYPE (decl))))
391 		{
392 		  auto_diagnostic_group d;
393 		  error ("%qT is not a nested class of %qT",
394 			 name, ctype);
395 		  inform (DECL_SOURCE_LOCATION (decl),
396 			  "%qD declared here", decl);
397 		  return;
398 		}
399 
400 	      friend_type = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl));
401 	    }
402 	}
403     }
404   else if (TREE_CODE (friend_type) == TEMPLATE_TYPE_PARM)
405     {
406       /* template <class T> friend class T; */
407       error ("template parameter type %qT declared %<friend%>", friend_type);
408       return;
409     }
410   else if (TREE_CODE (friend_type) == TEMPLATE_TEMPLATE_PARM)
411     friend_type = TYPE_NAME (friend_type);
412   else if (!CLASSTYPE_TEMPLATE_INFO (friend_type))
413     {
414       /* template <class T> friend class A; where A is not a template */
415       error ("%q#T is not a template", friend_type);
416       return;
417     }
418   else
419     /* template <class T> friend class A; where A is a template */
420     friend_type = CLASSTYPE_TI_TEMPLATE (friend_type);
421 
422   if (friend_type == error_mark_node)
423     return;
424 
425   /* See if it is already a friend.  */
426   for (classes = CLASSTYPE_FRIEND_CLASSES (type);
427        classes;
428        classes = TREE_CHAIN (classes))
429     {
430       tree probe = TREE_VALUE (classes);
431 
432       if (TREE_CODE (friend_type) == TEMPLATE_DECL)
433 	{
434 	  if (friend_type == probe)
435 	    {
436 	      if (complain)
437 		warning (OPT_Wredundant_decls,
438 			 "%qD is already a friend of %qT", probe, type);
439 	      break;
440 	    }
441 	}
442       else if (TREE_CODE (probe) != TEMPLATE_DECL)
443 	{
444 	  if (same_type_p (probe, friend_type))
445 	    {
446 	      if (complain)
447 		warning (OPT_Wredundant_decls,
448 			 "%qT is already a friend of %qT", probe, type);
449 	      break;
450 	    }
451 	}
452     }
453 
454   if (!classes)
455     {
456       maybe_add_class_template_decl_list (type, friend_type, /*friend_p=*/1);
457 
458       CLASSTYPE_FRIEND_CLASSES (type)
459 	= tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
460       if (TREE_CODE (friend_type) == TEMPLATE_DECL)
461 	friend_type = TREE_TYPE (friend_type);
462       if (!uses_template_parms (type))
463 	CLASSTYPE_BEFRIENDING_CLASSES (friend_type)
464 	  = tree_cons (NULL_TREE, type,
465 		       CLASSTYPE_BEFRIENDING_CLASSES (friend_type));
466     }
467 }
468 
469 /* Record DECL (a FUNCTION_DECL) as a friend of the
470    CURRENT_CLASS_TYPE.  If DECL is a member function, SCOPE is the
471    class of which it is a member, as named in the friend declaration.
472    If the friend declaration was explicitly namespace-qualified, SCOPE
473    is that namespace.
474    DECLARATOR is the name of the friend.  FUNCDEF_FLAG is true if the
475    friend declaration is a definition of the function.  FLAGS is as
476    for grokclass fn.  */
477 
478 tree
do_friend(tree scope,tree declarator,tree decl,tree attrlist,enum overload_flags flags,bool funcdef_flag)479 do_friend (tree scope, tree declarator, tree decl,
480 	   tree attrlist, enum overload_flags flags,
481 	   bool funcdef_flag)
482 {
483   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
484 
485   tree ctype = NULL_TREE;
486   tree in_namespace = NULL_TREE;
487   if (!scope)
488     ;
489   else if (MAYBE_CLASS_TYPE_P (scope))
490     ctype = scope;
491   else
492     {
493       gcc_checking_assert (TREE_CODE (scope) == NAMESPACE_DECL);
494       in_namespace = scope;
495     }
496 
497   /* Every decl that gets here is a friend of something.  */
498   DECL_FRIEND_P (decl) = 1;
499 
500   if (DECL_OVERRIDE_P (decl) || DECL_FINAL_P (decl))
501     error ("friend declaration %qD may not have virt-specifiers",
502 	   decl);
503 
504   /* Unfortunately, we have to handle attributes here.  Normally we would
505      handle them in start_decl_1, but since this is a friend decl start_decl_1
506      never gets to see it.  */
507 
508   /* Set attributes here so if duplicate decl, will have proper attributes.  */
509   cplus_decl_attributes (&decl, attrlist, 0);
510 
511   if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
512     {
513       declarator = TREE_OPERAND (declarator, 0);
514       if (!identifier_p (declarator))
515 	declarator = OVL_NAME (declarator);
516     }
517 
518   if (ctype)
519     {
520       /* CLASS_TEMPLATE_DEPTH counts the number of template headers for
521 	 the enclosing class.  FRIEND_DEPTH counts the number of template
522 	 headers used for this friend declaration.  TEMPLATE_MEMBER_P is
523 	 true if a template header in FRIEND_DEPTH is intended for
524 	 DECLARATOR.  For example, the code
525 
526 	   template <class T> struct A {
527 	     template <class U> struct B {
528 	       template <class V> template <class W>
529 		 friend void C<V>::f(W);
530 	     };
531 	   };
532 
533 	 will eventually give the following results
534 
535 	 1. CLASS_TEMPLATE_DEPTH equals 2 (for `T' and `U').
536 	 2. FRIEND_DEPTH equals 2 (for `V' and `W').
537 	 3. TEMPLATE_MEMBER_P is true (for `W').  */
538 
539       int class_template_depth = template_class_depth (current_class_type);
540       int friend_depth = processing_template_decl - class_template_depth;
541       /* We will figure this out later.  */
542       bool template_member_p = false;
543 
544       tree cname = TYPE_NAME (ctype);
545       if (TREE_CODE (cname) == TYPE_DECL)
546 	cname = DECL_NAME (cname);
547 
548       /* A method friend.  */
549       if (flags == NO_SPECIAL && declarator == cname)
550 	DECL_CXX_CONSTRUCTOR_P (decl) = 1;
551 
552       grokclassfn (ctype, decl, flags);
553 
554       if (friend_depth)
555 	{
556 	  if (!uses_template_parms_level (ctype, class_template_depth
557 						 + friend_depth))
558 	    template_member_p = true;
559 	}
560 
561       /* A nested class may declare a member of an enclosing class
562 	 to be a friend, so we do lookup here even if CTYPE is in
563 	 the process of being defined.  */
564       if (class_template_depth
565 	  || COMPLETE_OR_OPEN_TYPE_P (ctype))
566 	{
567 	  if (DECL_TEMPLATE_INFO (decl))
568 	    /* DECL is a template specialization.  No need to
569 	       build a new TEMPLATE_DECL.  */
570 	    ;
571 	  else if (class_template_depth)
572 	    /* We rely on tsubst_friend_function to check the
573 	       validity of the declaration later.  */
574 	    decl = push_template_decl_real (decl, /*is_friend=*/true);
575 	  else
576 	    decl = check_classfn (ctype, decl,
577 				  template_member_p
578 				  ? current_template_parms
579 				  : NULL_TREE);
580 
581 	  if ((template_member_p
582 	       /* Always pull out the TEMPLATE_DECL if we have a friend
583 		  template in a class template so that it gets tsubsted
584 		  properly later on (59956).  tsubst_friend_function knows
585 		  how to tell this apart from a member template.  */
586 	       || (class_template_depth && friend_depth))
587 	      && decl && TREE_CODE (decl) == FUNCTION_DECL)
588 	    decl = DECL_TI_TEMPLATE (decl);
589 
590 	  if (decl)
591 	    add_friend (current_class_type, decl, /*complain=*/true);
592 	}
593       else
594 	error ("member %qD declared as friend before type %qT defined",
595 		  decl, ctype);
596     }
597   /* A global friend.
598      @@ or possibly a friend from a base class ?!?  */
599   else if (TREE_CODE (decl) == FUNCTION_DECL)
600     {
601       int is_friend_template = PROCESSING_REAL_TEMPLATE_DECL_P ();
602 
603       /* Friends must all go through the overload machinery,
604 	 even though they may not technically be overloaded.
605 
606 	 Note that because classes all wind up being top-level
607 	 in their scope, their friend wind up in top-level scope as well.  */
608       if (funcdef_flag)
609 	SET_DECL_FRIEND_CONTEXT (decl, current_class_type);
610 
611       if (! DECL_USE_TEMPLATE (decl))
612 	{
613 	  /* We must check whether the decl refers to template
614 	     arguments before push_template_decl_real adds a
615 	     reference to the containing template class.  */
616 	  int warn = (warn_nontemplate_friend
617 		      && ! funcdef_flag && ! is_friend_template
618 		      && current_template_parms
619 		      && uses_template_parms (decl));
620 
621 	  if (is_friend_template
622 	      || template_class_depth (current_class_type) != 0)
623 	    /* We can't call pushdecl for a template class, since in
624 	       general, such a declaration depends on template
625 	       parameters.  Instead, we call pushdecl when the class
626 	       is instantiated.  */
627 	    decl = push_template_decl_real (decl, /*is_friend=*/true);
628 	  else if (current_function_decl && !in_namespace)
629 	    /* pushdecl will check there's a local decl already.  */
630 	    decl = pushdecl (decl, /*is_friend=*/true);
631 	  else
632 	    {
633 	      /* We can't use pushdecl, as we might be in a template
634 		 class specialization, and pushdecl will insert an
635 		 unqualified friend decl into the template parameter
636 		 scope, rather than the namespace containing it.  */
637 	      tree ns = decl_namespace_context (decl);
638 
639 	      push_nested_namespace (ns);
640 	      decl = pushdecl_namespace_level (decl, /*is_friend=*/true);
641 	      pop_nested_namespace (ns);
642 	    }
643 
644 	  if (warn)
645 	    {
646 	      static int explained;
647 	      bool warned;
648 
649 	      auto_diagnostic_group d;
650 	      warned = warning (OPT_Wnon_template_friend, "friend declaration "
651 				"%q#D declares a non-template function", decl);
652 	      if (! explained && warned)
653 		{
654 		  inform (input_location, "(if this is not what you intended, "
655 			  "make sure the function template has already been "
656 			  "declared and add %<<>%> after the function name "
657 			  "here)");
658 		  explained = 1;
659 		}
660 	    }
661 	}
662 
663       if (decl == error_mark_node)
664 	return error_mark_node;
665 
666       add_friend (current_class_type,
667 		  is_friend_template ? DECL_TI_TEMPLATE (decl) : decl,
668 		  /*complain=*/true);
669       DECL_FRIEND_P (decl) = 1;
670     }
671 
672   return decl;
673 }
674 
675 #include "gt-cp-friend.h"
676