public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
@ 2001-10-04 19:33 mike stump
  2001-10-05  3:01 ` Jakub Jelinek
  0 siblings, 1 reply; 19+ messages in thread
From: mike stump @ 2001-10-04 19:33 UTC (permalink / raw)
  To: kenner; +Cc: gcc

> Date: Thu, 4 Oct 01 22:25:34 EDT
> From: kenner@vlsi1.ultra.nyu.edu (Richard Kenner)
> To: mrs@windriver.com
> Cc: gcc@gcc.gnu.org

>     In a frontend, we never play with modes...  The type can be found in
>     TREE_TYPE, and you should just use it.  This is frontend code.

> Mostly, but not totally, true.  When stripping NOPs to look for
> things, it's not uncommon for frontends to only strip NOPs that
> don't change the mode.

Sure, but you're going into way too much detail here.  I'd just add,
just in case people don't see the difference, bool != int, from a type
system perspective, it doesn't matter if they both are 32 bits.
Comparing modes can have them be the same.  Comparing types, they
never are, well, cept maybe in C when you use a typedef.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
  2001-10-04 19:33 new __builtin_choose_type (patch) (new builtin_equal_types patch) mike stump
@ 2001-10-05  3:01 ` Jakub Jelinek
  2001-10-05  4:02   ` Joseph S. Myers
  0 siblings, 1 reply; 19+ messages in thread
From: Jakub Jelinek @ 2001-10-05  3:01 UTC (permalink / raw)
  To: mike stump; +Cc: kenner, gcc

On Thu, Oct 04, 2001 at 07:33:13PM -0700, mike stump wrote:
> > Date: Thu, 4 Oct 01 22:25:34 EDT
> > From: kenner@vlsi1.ultra.nyu.edu (Richard Kenner)
> > To: mrs@windriver.com
> > Cc: gcc@gcc.gnu.org
> 
> >     In a frontend, we never play with modes...  The type can be found in
> >     TREE_TYPE, and you should just use it.  This is frontend code.
> 
> > Mostly, but not totally, true.  When stripping NOPs to look for
> > things, it's not uncommon for frontends to only strip NOPs that
> > don't change the mode.
> 
> Sure, but you're going into way too much detail here.  I'd just add,
> just in case people don't see the difference, bool != int, from a type
> system perspective, it doesn't matter if they both are 32 bits.
> Comparing modes can have them be the same.  Comparing types, they
> never are, well, cept maybe in C when you use a typedef.

Maybe both kinds of type comparisons are useful, so perhaps we could have
__builtin_types_equal_p (x, y) which would return non-zero if
TYPE_MAIN_VARIANTs are the same and __builtin_modes_equal_p (x, y) which
would return non-zero if the TYPE_MODEs are the same. I guess the latter
would be what altivec would like to use (and probably tgmath.h as well).
BTW: stripping NOPs is problematic here, because I think
double d;
float f;
__builtin_modes_equal_p (f, d) should be false,
__builtin_modes_equal_p ((double) f, d) should be true,
int i;
char c;
__builtin_modes_equal_p (i, c) should be false,
__builtin_modes_equal_p (i, (int) c) should be true. The code has to
differentiate between NOPs added by the compiler because of argument
promotions and explicit casts.

	Jakub

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
  2001-10-05  3:01 ` Jakub Jelinek
@ 2001-10-05  4:02   ` Joseph S. Myers
  2001-10-05 16:14     ` Richard Henderson
  2001-10-07 16:56     ` Aldy Hernandez
  0 siblings, 2 replies; 19+ messages in thread
From: Joseph S. Myers @ 2001-10-05  4:02 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc

On Fri, 5 Oct 2001, Jakub Jelinek wrote:

> Maybe both kinds of type comparisons are useful, so perhaps we could have
> __builtin_types_equal_p (x, y) which would return non-zero if
> TYPE_MAIN_VARIANTs are the same and __builtin_modes_equal_p (x, y) which
> would return non-zero if the TYPE_MODEs are the same. I guess the latter
> would be what altivec would like to use (and probably tgmath.h as well).

tgmath.h should use the types, not the modes.  If float, double and long
double all have the same representation, calls should still go to the
correct function (even though the functions are probably aliases).

I think the following (which would need to be grammer symbols rather than
simple built-in functions) should suffice:

__builtin_types_compatible_p (T1, T2) - returns 1 if the unqualified
versions of the types T1 and T2 (which are types, not expressions) are
compatible, 0 otherwise, and can be used in integer constant expressions.

__builtin_choose_expr (C, E1, E2) - returns E1 (and has the type of E1) if
C is true, otherwise returns E2 (and has the type of E2).  C must be an
integer constant expression.

The first needs to be a grammer symbol because it takes types as
arguments.  The second needs to be a grammar symbol because of the
variable return type and to avoid default argument promotions on its
arguments.

Optionally, __builtin_choose_type could be provided as well as
__builtin_choose_expr.

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
  2001-10-05  4:02   ` Joseph S. Myers
@ 2001-10-05 16:14     ` Richard Henderson
  2001-10-05 16:38       ` Joseph S. Myers
  2001-10-07 16:56     ` Aldy Hernandez
  1 sibling, 1 reply; 19+ messages in thread
From: Richard Henderson @ 2001-10-05 16:14 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Jakub Jelinek, gcc

On Fri, Oct 05, 2001 at 12:02:32PM +0100, Joseph S. Myers wrote:
> I think the following (which would need to be grammer symbols rather than
> simple built-in functions) should suffice:
> 
> __builtin_types_compatible_p (T1, T2) - returns 1 if the unqualified
> versions of the types T1 and T2 (which are types, not expressions) are
> compatible, 0 otherwise, and can be used in integer constant expressions.

Yep.

> __builtin_choose_expr (C, E1, E2) - returns E1 (and has the type of E1) if
> C is true, otherwise returns E2 (and has the type of E2).  C must be an
> integer constant expression.

Ideally, we would want that if C is true E2 is not checked for
semantic correctness.  That is,

  int x;
  __builtin_choose_expr(1, 2, x->foo)

evaluates to 2 without error.  I'm not sure we can do this with
our current front end though.


r~

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
  2001-10-05 16:14     ` Richard Henderson
@ 2001-10-05 16:38       ` Joseph S. Myers
  2001-10-05 16:57         ` Richard Henderson
  0 siblings, 1 reply; 19+ messages in thread
From: Joseph S. Myers @ 2001-10-05 16:38 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Jakub Jelinek, gcc

On Fri, 5 Oct 2001, Richard Henderson wrote:

> > __builtin_choose_expr (C, E1, E2) - returns E1 (and has the type of E1) if
> > C is true, otherwise returns E2 (and has the type of E2).  C must be an
> > integer constant expression.
> 
> Ideally, we would want that if C is true E2 is not checked for
> semantic correctness.  That is,
> 
>   int x;
>   __builtin_choose_expr(1, 2, x->foo)
> 
> evaluates to 2 without error.  I'm not sure we can do this with
> our current front end though.

In C++, I expect that the new parser can do this easily.  In C, you could
perhaps develop a kludge: suppress but store the error and warning
messages while parsing the expressions, then regurgitate them for the
expression that gets selected.  The new parser branch contains the
required diagnostic machinery to do this.  (However, in C an expression
can declare new types, and any declarations from the ignored expression
would still remain in scope.)

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
  2001-10-05 16:38       ` Joseph S. Myers
@ 2001-10-05 16:57         ` Richard Henderson
  0 siblings, 0 replies; 19+ messages in thread
From: Richard Henderson @ 2001-10-05 16:57 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Jakub Jelinek, gcc

On Sat, Oct 06, 2001 at 12:38:36AM +0100, Joseph S. Myers wrote:
> In C++, I expect that the new parser can do this easily.  In C, you could
> perhaps develop a kludge: suppress but store the error and warning
> messages while parsing the expressions, then regurgitate them for the
> expression that gets selected.  The new parser branch contains the
> required diagnostic machinery to do this.  (However, in C an expression
> can declare new types, and any declarations from the ignored expression
> would still remain in scope.)

I'd been thinking more along the lines of having parsing and
semantic analysis separated into two phases.  Mucking with
diagnostics is probably easier though.


r~

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
  2001-10-05  4:02   ` Joseph S. Myers
  2001-10-05 16:14     ` Richard Henderson
@ 2001-10-07 16:56     ` Aldy Hernandez
  2001-10-07 17:06       ` Joseph S. Myers
  1 sibling, 1 reply; 19+ messages in thread
From: Aldy Hernandez @ 2001-10-07 16:56 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Jakub Jelinek, gcc

>>>>> "Joseph" == Joseph S Myers <jsm28@cam.ac.uk> writes:

Ok, sorry for the delay.

 > __builtin_choose_expr (C, E1, E2) - returns E1 (and has the type of E1) if
 > C is true, otherwise returns E2 (and has the type of E2).  C must be an
 > integer constant expression.

So C is a constant?  If so, is the following patch what is needed for
__buildin_choose_expr?

Cheers.
Aldy

2001-10-07  Aldy Hernandez  <aldyh@redhat.com>

	* c-common.h (rid): Add RID_CHOOSE_EXPR.

	* c-parse.in (reswords): Add __builtin_choose_expr.
	Add CHOOSE_EXPR token.
        Add production for CHOOSE_EXPR.

Index: c-parse.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-parse.in,v
retrieving revision 1.106
diff -c -p -r1.106 c-parse.in
*** c-parse.in	2001/09/21 01:26:52	1.106
--- c-parse.in	2001/10/07 23:55:27
*************** end ifc
*** 121,127 ****
  %token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
  %token BREAK CONTINUE RETURN GOTO ASM_KEYWORD TYPEOF ALIGNOF
  %token ATTRIBUTE EXTENSION LABEL
! %token REALPART IMAGPART VA_ARG
  %token PTR_VALUE PTR_BASE PTR_EXTENT
  
  /* function name can be a string const or a var decl. */
--- 121,127 ----
  %token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
  %token BREAK CONTINUE RETURN GOTO ASM_KEYWORD TYPEOF ALIGNOF
  %token ATTRIBUTE EXTENSION LABEL
! %token REALPART IMAGPART VA_ARG CHOOSE_EXPR
  %token PTR_VALUE PTR_BASE PTR_EXTENT
  
  /* function name can be a string const or a var decl. */
*************** primary:
*** 710,715 ****
--- 710,717 ----
  		{ $$ = build_function_call ($1, $3); }
  	| VA_ARG '(' expr_no_commas ',' typename ')'
  		{ $$ = build_va_arg ($3, groktypename ($5)); }
+ 	| CHOOSE_EXPR '(' CONSTANT ',' expr_no_commas ',' expr_no_commas ')'
+ 		{ $$ = integer_zerop ($3) ? $7 : $5; }
  	| primary '[' expr ']'   %prec '.'
  		{ $$ = build_array_ref ($1, $3); }
  	| primary '.' identifier
*************** static const struct resword reswords[] =
*** 3290,3295 ****
--- 3292,3298 ----
    { "__attribute__",	RID_ATTRIBUTE,	0 },
    { "__bounded",	RID_BOUNDED,	0 },
    { "__bounded__",	RID_BOUNDED,	0 },
+   { "__builtin_choose_expr", RID_CHOOSE_EXPR, 0 },
    { "__builtin_va_arg",	RID_VA_ARG,	0 },
    { "__complex",	RID_COMPLEX,	0 },
    { "__complex__",	RID_COMPLEX,	0 },
*************** static const short rid_to_yy[RID_MAX] =
*** 3461,3466 ****
--- 3464,3470 ----
    /* RID_PTRBASE */	PTR_BASE,
    /* RID_PTREXTENT */	PTR_EXTENT,
    /* RID_PTRVALUE */	PTR_VALUE,
+   /* RID_CHOOSE_EXPR */	CHOOSE_EXPR,
  
    /* RID_FUNCTION_NAME */		STRING_FUNC_NAME,
    /* RID_PRETTY_FUNCTION_NAME */	STRING_FUNC_NAME,
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.h,v
retrieving revision 1.85
diff -c -p -r1.85 c-common.h
*** c-common.h	2001/09/22 13:14:34	1.85
--- c-common.h	2001/10/07 23:55:27
*************** enum rid
*** 74,80 ****
    /* C extensions */
    RID_ASM,       RID_TYPEOF,   RID_ALIGNOF,  RID_ATTRIBUTE,  RID_VA_ARG,
    RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL,      RID_PTRBASE,
!   RID_PTREXTENT, RID_PTRVALUE,
  
    /* Too many ways of getting the name of a function as a string */
    RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME,
--- 74,80 ----
    /* C extensions */
    RID_ASM,       RID_TYPEOF,   RID_ALIGNOF,  RID_ATTRIBUTE,  RID_VA_ARG,
    RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL,      RID_PTRBASE,
!   RID_PTREXTENT, RID_PTRVALUE, RID_CHOOSE_EXPR,
  
    /* Too many ways of getting the name of a function as a string */
    RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME,

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
  2001-10-07 16:56     ` Aldy Hernandez
@ 2001-10-07 17:06       ` Joseph S. Myers
  2001-10-07 19:36         ` new __builtin_choose_type (patch) (new builtin_equal_typespatch) Aldy Hernandez
  0 siblings, 1 reply; 19+ messages in thread
From: Joseph S. Myers @ 2001-10-07 17:06 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Jakub Jelinek, gcc

On 7 Oct 2001, Aldy Hernandez wrote:

> So C is a constant?  If so, is the following patch what is needed for
> __buildin_choose_expr?

Except that:

* C is an *integer constant expression*, not necessarily a literal
constant.  (For example, it might be the return value of
__builtin_types_compatible_p.)

* An implementation for C++ is also needed.

* You should probably wait for the new C++ parser to be merged to the
mainline before doing this, since that will allow you to ignore errors and
warnings in the unused branch, per RTH's comments and my reply to them.

* To use this for type-generic functions, the __builtin_choose_expr goes
together with __builtin_types_compatible_p which needs implementing as
well.

* The actual patch submitted for inclusion in GCC should come with a
corresponding patch to glibc's <tgmath.h> that makes it a lot simpler and
more comprehensible (in the case of a new compiler) and passes glibc's
testsuite, as a sanity check that the proposed built-ins are useful for
their intended purpose.

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_typespatch)
  2001-10-07 17:06       ` Joseph S. Myers
@ 2001-10-07 19:36         ` Aldy Hernandez
  2001-10-08  3:46           ` new __builtin_choose_type (patch) (new builtin_equal_types patch) Joseph S. Myers
  0 siblings, 1 reply; 19+ messages in thread
From: Aldy Hernandez @ 2001-10-07 19:36 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Jakub Jelinek, gcc

> * C is an *integer constant expression*, not necessarily a literal
> constant.  (For example, it might be the return value of
> __builtin_types_compatible_p.)

fixed

> 
> * An implementation for C++ is also needed.

will wait for new front end like suggested.  [when's that?]

> * To use this for type-generic functions, the __builtin_choose_expr 
> goes together with __builtin_types_compatible_p which needs
> implementing as well.

done.  see patch below.

> * The actual patch submitted for inclusion in GCC should come with a
> corresponding patch to glibc's <tgmath.h> that makes it a lot simpler

uhhh, will have to work on this.  i hate tgmath.h :)

without further ado, here are the patches for  both
__builtin_choose_expr and __builtin_types_compatible_p, test cases and
docs.  i hope this one makes everone happy.

as a side note... i'm not a big fan of these big huge builtin names. 
it'll make tgmath.h horrendous to write (specially when combining
__builtin_types_compatible_p and __builtin_choose_expr in one line).

please comment...

cheers
aldy

-- 
Aldy Hernandez					E-mail: aldyh@redhat.com
Professional Gypsy on a [broken] Motorcycle
Red Hat, Inc.

2001-10-07  Aldy Hernandez  <aldyh@redhat.com>

	* testsuite/gcc.c-torture/execute/builtin-types-compatible-p.c: New.

	* testsuite/gcc.c-torture/execute/builtin-choose-expr.c: New.

	* c-common.h (rid): Add RID_CHOOSE_EXPR and
	RID_TYPES_COMPATIBLE_P.

        * c-parse.in (reswords): Add __builtin_choose_expr.
        Add __builtin_types_compatible_p.
        Add CHOOSE_EXPR token.
	Add TYPES_COMPATIBLE_P token.
        Add production for CHOOSE_EXPR.
	Add production for TYPES_COMPATIBLE_P.

        * doc/extend.texi (__builtin_choose_expr): New.
	(__builtin_types_compatible_p):	New.

Index: doc/extend.texi
===================================================================
RCS file: /cvs/gcc/egcs/gcc/doc/extend.texi,v
retrieving revision 1.27
diff -c -p -r1.27 extend.texi
*** extend.texi	2001/10/02 23:15:55	1.27
--- extend.texi	2001/10/08 02:28:35
*************** the same names as the standard macros ( 
*** 4342,4347 ****
--- 4342,4403 ----
  prefixed.  We intend for a library implementor to be able to simply
  @code{#define} each standard macro to its built-in equivalent.
  
+ @deftypefn {Built-in Function} int __builtin_types_compatible_p (@var{type1},
+ @var{type2})
+ 
+ You can use the builtin function @code{__builtin_types_compatible_p} to
+ determine whether two types are the same.  This builtin ignores top
+ level qualifiers (e.g. const, static).  If the types are the same, this
+ builtin returns the integer constant 1.  Otherwise, 0 is returned.
+ 
+ You would typically use this function in code whose execution varies
+ depending on the arguments' types.  For example:
+ 
+ @smallexample
+ #define foo(x)								\
+   ({									\
+     typeof (x) tmp;							\
+     if (__builtin_types_compatible_p (typeof (x), long double))		\
+       tmp = foo_long_double (tmp);					\
+     else if (__builtin_types_compatible_p (typeof (x), double))		\
+       tmp = foo_double (tmp);						\
+     else if (__builtin_types_compatible_p (typeof (x), float))		\
+       tmp = foo_float (tmp);						\
+     else								\
+       abort ();								\
+     tmp;								\
+   })
+ @end smallexample
+ 
+ @end deftypefn
+ 
+ @deftypefn {Built-in Function} int __builtin_choose_expr (@var{const_exp},
+ @var{exp1}, @var{exp2})
+ 
+ You can use the builtin function @code{__builtin_choose_expr} to
+ evaluate code depending on the value of a constant expression.  This
+ builtin returns exp1 if the constant expression const_exp is non zero.
+ Otherwise it returns 0.
+ 
+ If exp1 is returned, the return type is the same as exp1's type.  The
+ expression returned has its type unaltered by promotion rules.
+ Similarly, if exp2 is returned, its return type is the same as exp2.
+ 
+ Example:
+ 
+ @smallexample
+ #define foo(x)								     \
+   __builtin_choose_expr (__builtin_types_compatible_p (typeof (x), double),  \
+     foo_double (x),							     \
+     __builtin_choose_expr (__builtin_types_compatible_p (typeof (x), float), \
+       foo_float (x),							     \
+       /* The void expression results in a compile-time error		     \
+          when assigning the result to something.  */ 			     \
+       (void)0))
+ @end smallexample
+ 
+ @end deftypefn
+ 
  @deftypefn {Built-in Function} int __builtin_constant_p (@var{exp})
  You can use the built-in function @code{__builtin_constant_p} to
  determine if a value is known to be constant at compile-time and hence
Index: testsuite/gcc.c-torture/execute/builtin-types-compatible-p.c
===================================================================
RCS file: builtin-types-compatible-p.c
diff -N builtin-types-compatible-p.c
*** /dev/null	Tue May  5 13:32:27 1998
--- builtin-types-compatible-p.c	Sun Oct  7 19:28:35 2001
***************
*** 0 ****
--- 1,15 ----
+ int i;
+ double d;
+ 
+ main ()
+ {
+   if (__builtin_types_compatible_p (typeof (i), typeof (d)))
+     exit (1);
+   if (!__builtin_types_compatible_p (int, const int))
+     exit (1);
+   if (__builtin_types_compatible_p (char, int))
+     exit (1);
+   if (__builtin_types_compatible_p (long double, double))
+     exit (1);
+   exit (0);
+ }
Index: testsuite/gcc.c-torture/execute/builtin-choose-expr.c
===================================================================
RCS file: builtin-choose-expr.c
diff -N builtin-choose-expr.c
*** /dev/null	Tue May  5 13:32:27 1998
--- builtin-choose-expr.c	Sun Oct  7 19:28:35 2001
***************
*** 0 ****
--- 1,10 ----
+ main ()
+ {
+   if (__builtin_choose_expr (45, 0, 22))
+     exit (1);
+   if (__builtin_choose_expr (0, 12, 0))
+     exit (1);
+   if (!__builtin_choose_expr (45, 3, 0))
+     exit (1);
+   exit (0);
+ }
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.h,v
retrieving revision 1.85
diff -c -p -r1.85 c-common.h
*** c-common.h	2001/09/22 13:14:34	1.85
--- c-common.h	2001/10/08 02:28:35
*************** enum rid
*** 74,80 ****
    /* C extensions */
    RID_ASM,       RID_TYPEOF,   RID_ALIGNOF,  RID_ATTRIBUTE,  RID_VA_ARG,
    RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL,      RID_PTRBASE,
!   RID_PTREXTENT, RID_PTRVALUE,
  
    /* Too many ways of getting the name of a function as a string */
    RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME,
--- 74,80 ----
    /* C extensions */
    RID_ASM,       RID_TYPEOF,   RID_ALIGNOF,  RID_ATTRIBUTE,  RID_VA_ARG,
    RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL,      RID_PTRBASE,
!   RID_PTREXTENT, RID_PTRVALUE, RID_CHOOSE_EXPR, RID_TYPES_COMPATIBLE_P,
  
    /* Too many ways of getting the name of a function as a string */
    RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME,
Index: c-parse.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-parse.in,v
retrieving revision 1.106
diff -c -p -r1.106 c-parse.in
*** c-parse.in	2001/09/21 01:26:52	1.106
--- c-parse.in	2001/10/08 02:28:35
*************** end ifc
*** 121,127 ****
  %token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
  %token BREAK CONTINUE RETURN GOTO ASM_KEYWORD TYPEOF ALIGNOF
  %token ATTRIBUTE EXTENSION LABEL
! %token REALPART IMAGPART VA_ARG
  %token PTR_VALUE PTR_BASE PTR_EXTENT
  
  /* function name can be a string const or a var decl. */
--- 121,127 ----
  %token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
  %token BREAK CONTINUE RETURN GOTO ASM_KEYWORD TYPEOF ALIGNOF
  %token ATTRIBUTE EXTENSION LABEL
! %token REALPART IMAGPART VA_ARG CHOOSE_EXPR TYPES_COMPATIBLE_P
  %token PTR_VALUE PTR_BASE PTR_EXTENT
  
  /* function name can be a string const or a var decl. */
*************** primary:
*** 710,715 ****
--- 710,734 ----
  		{ $$ = build_function_call ($1, $3); }
  	| VA_ARG '(' expr_no_commas ',' typename ')'
  		{ $$ = build_va_arg ($3, groktypename ($5)); }
+ 	| CHOOSE_EXPR '(' expr_no_commas ',' expr_no_commas ',' expr_no_commas ')'
+ 		{
+ 		  tree c;
+ 
+ 		  c = fold ($3);
+ 		  STRIP_NOPS (c);
+ 		  if (TREE_CODE (c) != INTEGER_CST)
+ 		    error ("first argument to __builtin_choose_expr not a constant");
+ 		  $$ = integer_zerop (c) ? $7 : $5;
+ 		}
+ 	| TYPES_COMPATIBLE_P '(' typename ',' typename ')'
+ 	{
+ 	  tree e1, e2;
+ 
+ 	  e1 = TYPE_MAIN_VARIANT (groktypename ($3));
+ 	  e2 = TYPE_MAIN_VARIANT (groktypename ($5));
+ 
+ 	  $$ = e1 == e2 ? build_int_2 (1, 0) : build_int_2 (0, 0);
+ 	}
  	| primary '[' expr ']'   %prec '.'
  		{ $$ = build_array_ref ($1, $3); }
  	| primary '.' identifier
*************** static const struct resword reswords[] =
*** 3290,3295 ****
--- 3309,3316 ----
    { "__attribute__",	RID_ATTRIBUTE,	0 },
    { "__bounded",	RID_BOUNDED,	0 },
    { "__bounded__",	RID_BOUNDED,	0 },
+   { "__builtin_choose_expr", RID_CHOOSE_EXPR, 0 },
+   { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, 0 },
    { "__builtin_va_arg",	RID_VA_ARG,	0 },
    { "__complex",	RID_COMPLEX,	0 },
    { "__complex__",	RID_COMPLEX,	0 },
*************** static const short rid_to_yy[RID_MAX] =
*** 3461,3466 ****
--- 3482,3489 ----
    /* RID_PTRBASE */	PTR_BASE,
    /* RID_PTREXTENT */	PTR_EXTENT,
    /* RID_PTRVALUE */	PTR_VALUE,
+   /* RID_CHOOSE_EXPR */	CHOOSE_EXPR,
+   /* RID_TYPES_COMPATIBLE_P */ TYPES_COMPATIBLE_P,
  
    /* RID_FUNCTION_NAME */		STRING_FUNC_NAME,
    /* RID_PRETTY_FUNCTION_NAME */	STRING_FUNC_NAME,

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
  2001-10-07 19:36         ` new __builtin_choose_type (patch) (new builtin_equal_typespatch) Aldy Hernandez
@ 2001-10-08  3:46           ` Joseph S. Myers
  2001-10-08 12:46             ` new __builtin_choose_type (patch) (new builtin_equal_typespatch) Mark Mitchell
  0 siblings, 1 reply; 19+ messages in thread
From: Joseph S. Myers @ 2001-10-08  3:46 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Jakub Jelinek, gcc

On 7 Oct 2001, Aldy Hernandez wrote:

> > * An implementation for C++ is also needed.
> 
> will wait for new front end like suggested.  [when's that?]

I don't know whether it's currently on schedule for 3.1, or not.  The new
C++ parser will also help implement RTH's suggestion for C (that errors in
the unused half of __builtin_choose_expr be ignored) through its
diagnostic machinery.

> as a side note... i'm not a big fan of these big huge builtin names. 
> it'll make tgmath.h horrendous to write (specially when combining
> __builtin_types_compatible_p and __builtin_choose_expr in one line).

Naturally <tgmath.h> would have appropriate macros:

* one, given a real type, to compute the tgmath type (i.e., to convert 
integer types to real types);

* one, given a real or complex type, to compute the tgmath type;

* one, given two types, to compute the tgmath type associated with the 
pair (i.e., the type of the sum of values whose types are the tgmath types 
of the individual types - (int, float) maps to double);

* one, given a real type and three expressions (calls to float, double, 
long double functions) to choose the appropriate one;

* one, given a real or complex type and six expressions, to choose the 
appropriate one;

* versions of the existing __TGMATH_* macros that use the previous macros 
rather than using sizeof and __builtin_classify_type;

* optionally, to simplify these, you could define __type_float_p and
similar macros to abstract out __builtin_types_compatible_p.

The aim is to create something that is comprehensible and maintainable and
uses well-defined well-documented interfaces rather than the arcana of the
rules for types of conditional expressions, __builtin_classify_type and
statement expressions.

> + @deftypefn {Built-in Function} int __builtin_types_compatible_p (@var{type1},
> + @var{type2})
> + 
> + You can use the builtin function @code{__builtin_types_compatible_p} to

"built-in" not "builtin".  See the style notes in gcc.texi.

> + determine whether two types are the same.  This builtin ignores top

"built-in function" not "builtin".

> + level qualifiers (e.g. const, static).  If the types are the same, this

"e.g., @code{const}, @code{static}".

> + builtin returns the integer constant 1.  Otherwise, 0 is returned.

"built-in function".

It should test compatibility, not "same"ness.  (For example, "int []" is 
compatible with "int [10]".)  The types for which this makes a difference 
probably aren't that useful with this builtin in practice, but there may 
well be a use for e.g. handling enums like the integer type they are 
compatible with.  Type compatibility is a better-defined concept since the 
standard doesn't have to deal with "same"ness.

> + You can use the builtin function @code{__builtin_choose_expr} to

"built-in".

> + evaluate code depending on the value of a constant expression.  This

It must be an *integer* constant expression.

> + builtin returns exp1 if the constant expression const_exp is non zero.

@var{exp1}.  @var{const_exp}.  The spelling "non zero" doesn't seem to be 
used in the manual, but both "nonzero" and "non-zero" are widely used.  
(Which should be preferred?)

> + Otherwise it returns 0.

No, it returns exp2.

> + If exp1 is returned, the return type is the same as exp1's type.  The

@var{exp1}

> + expression returned has its type unaltered by promotion rules.
> + Similarly, if exp2 is returned, its return type is the same as exp2.

@var{exp2}

> +   if (__builtin_types_compatible_p (typeof (i), typeof (d)))
> +     exit (1);

You should test that this is an integer constant expression.  For example, 
use __builtin_types_compatible_p in static initializers.

> +   if (__builtin_choose_expr (45, 0, 22))
> +     exit (1);
> +   if (__builtin_choose_expr (0, 12, 0))
> +     exit (1);
> +   if (!__builtin_choose_expr (45, 3, 0))
> +     exit (1);

You need tests where the arguments are of different types, not necessarily
compatible.  Also test the type of the result.  Look at 
gcc.dg/c99-condexpr-1.c for an example of how to test types of expressions 
(this may mean using gcc.dg for this testcase).

> + 	  $$ = e1 == e2 ? build_int_2 (1, 0) : build_int_2 (0, 0);

Use comptypes, rather than comparing type pointers.  Use the existing
integer_zero_node and integer_one_node.

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_typespatch)
  2001-10-08  3:46           ` new __builtin_choose_type (patch) (new builtin_equal_types patch) Joseph S. Myers
@ 2001-10-08 12:46             ` Mark Mitchell
  0 siblings, 0 replies; 19+ messages in thread
From: Mark Mitchell @ 2001-10-08 12:46 UTC (permalink / raw)
  To: Joseph S. Myers, Aldy Hernandez; +Cc: Jakub Jelinek, gcc

--On Monday, October 08, 2001 11:45:39 AM +0100 "Joseph S. Myers" 
<jsm28@cam.ac.uk> wrote:

> On 7 Oct 2001, Aldy Hernandez wrote:
>
>> > * An implementation for C++ is also needed.
>>
>> will wait for new front end like suggested.  [when's that?]
>
> I don't know whether it's currently on schedule for 3.1, or not.  The new
> C++ parser will also help implement RTH's suggestion for C (that errors in
> the unused half of __builtin_choose_expr be ignored) through its
> diagnostic machinery.

At this point, I don't think it's going to make 3.1.  It's frustruating,
because it's 95% done -- but Nathan and I just aren't having the time
to make progress at a rate to get this done by the 15th.  It will
definitely be in 3.2.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
  2001-10-03 20:16 ` new __builtin_choose_type (patch) (new builtin_equal_typespatch) Aldy Hernandez
  2001-10-03 20:33   ` new __builtin_choose_type (patch) (new builtin_equal_types patch) Stan Shebs
  2001-10-03 20:53   ` Daniel Jacobowitz
@ 2001-10-05 16:04   ` Richard Henderson
  2 siblings, 0 replies; 19+ messages in thread
From: Richard Henderson @ 2001-10-05 16:04 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Magnus Fromreide, gcc

On Wed, Oct 03, 2001 at 11:19:45PM -0400, Aldy Hernandez wrote:
> +                         __builtin_equal_types (X, cd)	\
> +                           ? atan_complex_double (X)		\
> +                           : __builtin_equal_types (X, f)	\
> +                           ? atan_float (X)			\
> +                           /* Assume or convert to double.  */	\
> +                           : atan_double ((double) X); })

Incidentally, this example is wrong.  The result of the ?: operator
is promoted.


r~

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
  2001-10-05 11:47 new __builtin_choose_type (patch) (new builtin_equal_types patch) mike stump
@ 2001-10-05 11:52 ` Joseph S. Myers
  0 siblings, 0 replies; 19+ messages in thread
From: Joseph S. Myers @ 2001-10-05 11:52 UTC (permalink / raw)
  To: mike stump; +Cc: jakub, gcc

On Fri, 5 Oct 2001, mike stump wrote:

> There isn't much wrong with __builtin_same_type (*(T *)0, *(int*)0)...
> One can compare double to int, if one wants...  I don't favor a
> grammar extension, since a trivial work around exists.  Since these

That doesn't work as a built-in function.  To allow for the different
types it would need to be represented as a variadic function - but then
arguments of type float would be promoted to double, which isn't suitable
for implementing <tgmath.h>.

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
@ 2001-10-05 11:47 mike stump
  2001-10-05 11:52 ` Joseph S. Myers
  0 siblings, 1 reply; 19+ messages in thread
From: mike stump @ 2001-10-05 11:47 UTC (permalink / raw)
  To: jakub, jsm28; +Cc: gcc

> Date: Fri, 5 Oct 2001 12:02:32 +0100 (BST)
> From: "Joseph S. Myers" <jsm28@cam.ac.uk>
> To: Jakub Jelinek <jakub@redhat.com>
> cc: <gcc@gcc.gnu.org>

> I think the following (which would need to be grammer symbols rather than
> simple built-in functions) should suffice:

Ick!

There isn't much wrong with __builtin_same_type (*(T *)0, *(int*)0)...
One can compare double to int, if one wants...  I don't favor a
grammar extension, since a trivial work around exists.  Since these
things are not `evaluated' we aren't actually dereferencing 0.  This
allows these things to fit more naturally into the present framework.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
@ 2001-10-04 19:19 Richard Kenner
  0 siblings, 0 replies; 19+ messages in thread
From: Richard Kenner @ 2001-10-04 19:19 UTC (permalink / raw)
  To: mrs; +Cc: gcc

    In a frontend, we never play with modes...  The type can be found in
    TREE_TYPE, and you should just use it.  This is frontend code.

Mostly, but not totally, true.  When stripping NOPs to look for
things, it's not uncommon for frontends to only strip NOPs that don't
change the mode.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
@ 2001-10-04 19:09 mike stump
  0 siblings, 0 replies; 19+ messages in thread
From: mike stump @ 2001-10-04 19:09 UTC (permalink / raw)
  To: aldyh, magfr; +Cc: gcc

> From: Aldy Hernandez <aldyh@redhat.com>
> To: Magnus Fromreide <magfr@lysator.liu.se>
> Cc: gcc@gcc.gnu.org
> Date: 03 Oct 2001 23:19:45 -0400

> On Wed, 2001-10-03 at 04:15, Magnus Fromreide wrote:
> > It is my feeling that it would be more general and cleaner to do something
> > along the lines of
> > 
> > _Bool __builtin_equal_types(arg|type, arg|type)
> > 
> > that doesn't evaluate the arguments if they are expressions and answers
> > the question of wether they are of the same type.

> is everyone ok with this approach?

I like it...  A simple extension, easy to document and understand,
possibly generally useful, trivial to maintain.

> + static rtx
> + expand_builtin_equal_types (exp, target)
> +      tree exp;
> +      rtx target;
> + {
> +   tree arg = TREE_OPERAND (exp, 1);
> +   tree chain;
> +   enum machine_mode exp0_mode, exp1_mode;
> + 
> +   if (!arg)
> +     return const0_rtx;
> + 
> +   chain = TREE_CHAIN (arg);
> +   arg = TREE_VALUE (arg);
> + 
> +   /* Strip off all NOPs.  */
> +   while (TREE_CODE (arg) == NOP_EXPR
> + 	 || TREE_CODE (arg) == CONVERT_EXPR
> + 	 || TREE_CODE (arg) == NON_LVALUE_EXPR
> + 	 || TREE_CODE (arg) == INDIRECT_REF)
> +     arg = TREE_OPERAND (arg, 0);
> + 
> +   /* Get <exp0> type.  */
> +   exp0_mode = TYPE_MODE (TREE_TYPE (arg));

In a frontend, we never play with modes...  The type can be found in
TREE_TYPE, and you should just use it.  This is frontend code.

> +   /* Get <exp1> type.  */
> +   arg = TREE_VALUE (chain);
> +   if (!arg)
> +     error ("missing argument in `__builtin_equal_types'");
> +   /* Strip off all NOPs.  */
> +   while (TREE_CODE (arg) == NOP_EXPR
> + 	 || TREE_CODE (arg) == CONVERT_EXPR
> + 	 || TREE_CODE (arg) == NON_LVALUE_EXPR
> + 	 || TREE_CODE (arg) == INDIRECT_REF)
> +     arg = TREE_OPERAND (arg, 0);

Again, this is wrong.  We don't peek under peoples dresses.  The type
can be found in TREE_TYPE of arg, that is is't type, no other value
is, or is as good.  The tree type inside one of these things need not
match the outer type.

> +   exp1_mode = TYPE_MODE (TREE_TYPE (arg));

Again, no modes in frontend code.


Now, the hard part, which someone eluded to, is a const int == int?
If the are !=, the you want to just compare the types.  If they are
==, then you want to use TYPE_MAIN_VARIANT on them both before
comparing.  Also, the comparison will be tricky, see
cp/typeck.c:comptypes for all the hair for one language.  You might
have to have a callback for it, as the backend is kinda stupid.

Also, since each frontend can have a different notion of same type,
you'll have to come up with enough documentation to exactly describe
what you mean.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
  2001-10-03 20:53   ` Daniel Jacobowitz
@ 2001-10-04  6:02     ` Joseph S. Myers
  0 siblings, 0 replies; 19+ messages in thread
From: Joseph S. Myers @ 2001-10-04  6:02 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Aldy Hernandez, Magnus Fromreide, gcc

On Wed, 3 Oct 2001, Daniel Jacobowitz wrote:

> On Wed, Oct 03, 2001 at 11:19:45PM -0400, Aldy Hernandez wrote:
> > thought about it.  like it.  nice and clean.
> > 
> > is everyone ok with this approach?  it's pretty.  it's got
> > documentation.  it's got a test case. :)
> 
> ... but it could be prettier... I'd still like to push for a function
> which takes types as arguments.  You can use something like:
>  __builtin_equal_types (typeof(x), float)

Indeed, I think this is the preferred approach (so as a grammar element
rather than a simple built-in function) - once the notion of equality has
been defined.  (Though it should be called __builtin_types_equal_p.)

Since the concept of type compatibility is defined by ISO C, the
appropriate test might be that (after removing toplevel qualifiers)
instead of equality - in which case it should be
__builtin_types_compatible_p.

Does the present patch, which removes conversions, proerly compare a float
cast to double as being a double, and a double cast to float as being a
float?

The present patch needs to document the return type (int?) of the
built-in.

> Also, how does this function deal with qualifiers?  Is a const double
> equivalent to a double?  How about volatile?  Is 'signed int' the same
> as 'int'?

rvalues shouldn't have qualified type - but when used with typeof in
macros, it will need to allow for qualified type, and remove the
qualifiers.  signed int should count the same as int here, since the only
difference is when declaring bit-fields.

> From reading the patch, you're comparing modes, not types.  That needs
> to be reflected in the documentation, and possibly in the name of the
> function.  Saying two types are the 'same' without defining sameness
> isn't going to be enough.

Comparing modes isn't appropriate.  This should e.g. distinguish long and
int even on systems where they are the same size.

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
  2001-10-03 20:16 ` new __builtin_choose_type (patch) (new builtin_equal_typespatch) Aldy Hernandez
  2001-10-03 20:33   ` new __builtin_choose_type (patch) (new builtin_equal_types patch) Stan Shebs
@ 2001-10-03 20:53   ` Daniel Jacobowitz
  2001-10-04  6:02     ` Joseph S. Myers
  2001-10-05 16:04   ` Richard Henderson
  2 siblings, 1 reply; 19+ messages in thread
From: Daniel Jacobowitz @ 2001-10-03 20:53 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Magnus Fromreide, gcc

On Wed, Oct 03, 2001 at 11:19:45PM -0400, Aldy Hernandez wrote:
> thought about it.  like it.  nice and clean.
> 
> is everyone ok with this approach?  it's pretty.  it's got
> documentation.  it's got a test case. :)

... but it could be prettier... I'd still like to push for a function
which takes types as arguments.  You can use something like:
 __builtin_equal_types (typeof(x), float)

Also, how does this function deal with qualifiers?  Is a const double
equivalent to a double?  How about volatile?  Is 'signed int' the same
as 'int'?

From reading the patch, you're comparing modes, not types.  That needs
to be reflected in the documentation, and possibly in the name of the
function.  Saying two types are the 'same' without defining sameness
isn't going to be enough.

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
  2001-10-03 20:16 ` new __builtin_choose_type (patch) (new builtin_equal_typespatch) Aldy Hernandez
@ 2001-10-03 20:33   ` Stan Shebs
  2001-10-03 20:53   ` Daniel Jacobowitz
  2001-10-05 16:04   ` Richard Henderson
  2 siblings, 0 replies; 19+ messages in thread
From: Stan Shebs @ 2001-10-03 20:33 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Magnus Fromreide, gcc

Aldy Hernandez wrote:
> 
> On Wed, 2001-10-03 at 04:15, Magnus Fromreide wrote:
> > It is my feeling that it would be more general and cleaner to do something
> > along the lines of
> >
> > _Bool __builtin_equal_types(arg|type, arg|type)
> >
> > that doesn't evaluate the arguments if they are expressions and answers
> > the question of wether they are of the same type.
> >
> > Usage examples:
> >
> > __builtin_equal_types(x, y) ? no() : x = 10;
> > if(__builtin_equal_types(x, y))
> >   {
> >   }
> > else
> >   {
> >   }
> 
> thought about it.  like it.  nice and clean.
> 
> is everyone ok with this approach?  it's pretty.  it's got
> documentation.  it's got a test case. :)

Doesn't your patch still have the char->int promotion problem?
What does _builtin_equal_types(ch, i) return for variables that
are char and int, respectively?

Also, in honor of GCC's Lispy origins, it should be called
__builtin_equal_types_p . (Just kidding!)

Stan

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2001-10-08 12:46 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-10-04 19:33 new __builtin_choose_type (patch) (new builtin_equal_types patch) mike stump
2001-10-05  3:01 ` Jakub Jelinek
2001-10-05  4:02   ` Joseph S. Myers
2001-10-05 16:14     ` Richard Henderson
2001-10-05 16:38       ` Joseph S. Myers
2001-10-05 16:57         ` Richard Henderson
2001-10-07 16:56     ` Aldy Hernandez
2001-10-07 17:06       ` Joseph S. Myers
2001-10-07 19:36         ` new __builtin_choose_type (patch) (new builtin_equal_typespatch) Aldy Hernandez
2001-10-08  3:46           ` new __builtin_choose_type (patch) (new builtin_equal_types patch) Joseph S. Myers
2001-10-08 12:46             ` new __builtin_choose_type (patch) (new builtin_equal_typespatch) Mark Mitchell
  -- strict thread matches above, loose matches on Subject: below --
2001-10-05 11:47 new __builtin_choose_type (patch) (new builtin_equal_types patch) mike stump
2001-10-05 11:52 ` Joseph S. Myers
2001-10-04 19:19 Richard Kenner
2001-10-04 19:09 mike stump
2001-10-03  1:15 new __builtin_choose_type (patch) Magnus Fromreide
2001-10-03 20:16 ` new __builtin_choose_type (patch) (new builtin_equal_typespatch) Aldy Hernandez
2001-10-03 20:33   ` new __builtin_choose_type (patch) (new builtin_equal_types patch) Stan Shebs
2001-10-03 20:53   ` Daniel Jacobowitz
2001-10-04  6:02     ` Joseph S. Myers
2001-10-05 16:04   ` Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).