On Tue, May 31, 2016 at 04:44:45PM -0600, Martin Sebor wrote: > >I fail to understand this. You set type to NULL_TREE, and then (not in any > >kind of loop, nor any label you could goto to) do: > > type = type ? type : xxx; > >That is necessarily equal to type = xxx;, isn't it? > > Each label falls through to the next, so the test prevents > the subsequent labels from overwriting the value assigned > to type by the label that matched the switch expression. > I'm not exactly enamored with these repetitive tests but > the only alternative that occurred to me was to duplicate > the whole switch statement, and this seemed like the lesser > of the two evils. If you have a suggestion for something > better I'd be happy to change it.
Ugh, I've missed missing break; Anyway, IMHO we shouldn't change the old style builtins and therefore you really don't need this. > >>+ /* When the last argument is a NULL pointer and the first two arguments > >>+ are constant, attempt to fold the built-in call into a constant > >>+ expression indicating whether or not it detected an overflow but > >>+ without storing the result. */ > >>+ if ((!arg2 || zerop (arg2)) > > > >As I said in another mail, IMNSHO you don't want to change the clang > >compatibility builtins, therefore arg2 should never be NULL. > > Allowing the last argument to be null is the subject of > the enhancement request in c/68120 (one of the two PRs > driving this enhancement). The argument can only be null > for these overloads and not the type-generic ones because > the latter use the type to which the pointer points to > determine the type in which to do the arithmetic. Without > this change, C or C++ 98 users wouldn't be able to use the > built-ins in constant expressions (C++ 98 doesn't allow > casting a null pointer in those contexts). Sorry, I don't understand this argument. What is wrong on using const int x = __builtin_add_overflow (1234567, 123456, (int *) NULL); ? I don't get any warning/error on #include <stddef.h> int *const p = (int *) NULL; in C89 nor C++98 with -pedantic-errors, not to mention that the builtins are extensions anyway, so what do you accept/reject in its arguments doesn't need to honor any specific rules. Even if (int *) NULL is not allowed for whatever reason, is (int *) 0 disallowed too? It is just a matter of what we document. The clang compatibility builtins are severely limited and too ugly to live with, they don't allow different types of the arguments, have just a very limited set of accepted types, don't allow different result type, how do you even handle a type for which you don't know if it is unsigned, unsigned long or unsigned long long? size_t a, b, c, d; ... if (sizeof (size_t) == sizeof (unsigned long long)) a = __builtin_uaddll_overflow (b, c, &d); else if (sizeof (size_t) == sizeof (unsigned long)) a = __builtin_uaddl_overflow (b, c, &d); else if (sizeof (size_t) == sizeof (unsigned int)) a = __builtin_uadd_overflow (b, c, &d); else abort (); ? We really shouldn't encourage these at all. > I suspect I didn't use integer_zerop because the argument > is a pointer and not integer, but I'll change it before > I commit the patch. Pointers are treated the same as integers, they are represented as INTEGER_CSTs too. > > >Regarding the varargs vs. named args only different diagnostics, if you > >think it should change, then IMHO you should submit as independent patch > >a change to the diagnostics wording, so that the wording is the same, rather > >than changing functions from fixed arguments to varargs (/ typegeneric). > > I'm not sure I know what part of the patch you're referring > to. Are you suggesting to submit a separate patch for the > change from "not enough arguments" to "too few arguments" > below? > > - "not enough arguments to function %qE", fndecl); > + "too few arguments to function %qE", fndecl); Yeah. IMO that is an independent change, you can/should add a testcase for it, and it can go in before or after the patch. Jakub