Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

clang allows forming pointer to function with cv-qualifier-seq or ref-qualifier #19741

Open Quuxplusone opened 10 years ago

Quuxplusone commented 10 years ago
Bugzilla Link PR19742
Status NEW
Importance P normal
Reported by Daniel Krügler (daniel.kruegler@gmail.com)
Reported on 2014-05-14 13:24:25 -0700
Last modified on 2016-02-19 10:59:25 -0800
Version trunk
Hardware PC Linux
CC dgregor@apple.com, droffset@yandex.ru, llvm-bugs@lists.llvm.org, pdaouadi@aldebaran-robotics.com, richard-llvm@metafoo.co.uk
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
When compiling the following code using C++11 options:

-Wall -Wextra -std=c++11 -pedantic

or using C++1y options:

-Wall -Wextra -std=c++1y -pedantic

it is accepted by clang 3.5 trunk 208701 or 3.4 final:

//---------------------
template<class T>
struct add_ptr
{
  using type = T*;
};

int main() {
  using FC = void () const;
  using PFC = add_ptr<FC>::type;
  using FLR = void () &;
  using PFLR = add_ptr<FLR>::type;
  using FRR = void () &&;
  using PFRR = add_ptr<FRR>::type;
}
//---------------------

After resolution of CWG 1417,

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1417

the formation of a pointer to function types with cv-qualifier or ref-qualifier
(even in template context) is not supported. In non-template context, clang
already rejects such an attempt.

The code had been compiled using the online-compiler

http://melpon.org/wandbox/

therefore the provided information about OS and hardware are guesses on my side.
Quuxplusone commented 10 years ago
Fixed in r208825, but I'm leaving this open because we're not done here yet. We
still incorrectly accept these:

  template<typename T> struct S {
    void f(T);
  };
  S<void () const> s1;
  S<void () &> s2;

... because we don't properly validate the pointer type we build when
performing function-to-pointer decay.
Quuxplusone commented 8 years ago
(In reply to comment #1)
> Fixed in r208825, but I'm leaving this open because we're not done here yet.
> We still incorrectly accept these:
>
>   template<typename T> struct S {
>     void f(T);
>   };
>   S<void () const> s1;
>   S<void () &> s2;
>
> ... because we don't properly validate the pointer type we build when
> performing function-to-pointer decay.

Good afternoon,

so, in the context of this question I would like to clarify, that this rule
(8.3.1/4):
"Forming a reference to function type is ill-formed if the function type has cv-
qualifiers or a ref-qualifier"

applicable for this code:

#include <iostream>

template <typename F>
void (* test()) (F);

template <typename X>
char (& probe( void(*) ( X * ) ) )[1];

template <typename X>
char (& probe( void(*) ( X   ) ) )[2];

int main()
{
    std::cout << sizeof(probe(test<void() const>()));
}
in context of C++14 standard (for versions 3.4 and earlier this code prints
"1", 3.5 and higher prints "2")?

And what about C++03 (in which there is no explicit limitation)? Behaviour
whould same, or not?