llvm-project/clang/test/SemaCXX/for-range-dereference.cpp
Ted Kremenek b79ee57080 Implemented delayed processing of 'unavailable' checking, just like with 'deprecated'.
Fixes <rdar://problem/15584219> and <rdar://problem/12241361>.

This change looks large, but all it does is reuse and consolidate
the delayed diagnostic logic for deprecation warnings with unavailability
warnings.  By doing so, it showed various inconsistencies between the
diagnostics, which were close, but not consistent.  It also revealed
some missing "note:"'s in the deprecated diagnostics that were showing
up in the unavailable diagnostics, etc.

This change also changes the wording of the core deprecation diagnostics.
Instead of saying "function has been explicitly marked deprecated"
we now saw "'X' has been been explicitly marked deprecated".  It
turns out providing a bit more context is useful, and often we
got the actual term wrong or it was not very precise
 (e.g., "function" instead of "destructor").  By just saying the name
of the thing that is deprecated/deleted/unavailable we define
this issue away.  This diagnostic can likely be further wordsmithed
to be shorter.

llvm-svn: 197627
2013-12-18 23:30:06 +00:00

90 lines
3.3 KiB
C++

// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
struct Data { };
struct T {
Data *begin();
Data *end();
};
struct NoBegin {
Data *end();
};
struct DeletedEnd : public T {
Data *begin();
Data *end() = delete; //expected-note {{'end' has been explicitly marked deleted here}}
};
struct DeletedADLBegin { };
int* begin(DeletedADLBegin) = delete; //expected-note {{candidate function has been explicitly deleted}} \
expected-note 5 {{candidate function not viable: no known conversion}}
struct PrivateEnd {
Data *begin();
private:
Data *end(); // expected-note 2 {{declared private here}}
};
struct ADLNoEnd { };
Data * begin(ADLNoEnd); // expected-note 6 {{candidate function not viable: no known conversion}}
struct OverloadedStar {
T operator*();
};
void f() {
T t;
for (auto i : t) { }
T *pt;
for (auto i : pt) { } // expected-error{{invalid range expression of type 'T *'; did you mean to dereference it with '*'?}}
int arr[10];
for (auto i : arr) { }
int (*parr)[10];
for (auto i : parr) { }// expected-error{{invalid range expression of type 'int (*)[10]'; did you mean to dereference it with '*'?}}
NoBegin NB;
for (auto i : NB) { }// expected-error{{range type 'NoBegin' has 'end' member but no 'begin' member}}
NoBegin *pNB;
for (auto i : pNB) { }// expected-error{{invalid range expression of type 'NoBegin *'; no viable 'begin' function available}}
NoBegin **ppNB;
for (auto i : ppNB) { }// expected-error{{invalid range expression of type 'NoBegin **'; no viable 'begin' function available}}
NoBegin *****pppppNB;
for (auto i : pppppNB) { }// expected-error{{invalid range expression of type 'NoBegin *****'; no viable 'begin' function available}}
ADLNoEnd ANE;
for (auto i : ANE) { } // expected-error{{invalid range expression of type 'ADLNoEnd'; no viable 'end' function available}}
ADLNoEnd *pANE;
for (auto i : pANE) { } // expected-error{{invalid range expression of type 'ADLNoEnd *'; no viable 'begin' function available}}
DeletedEnd DE;
for (auto i : DE) { } // expected-error{{attempt to use a deleted function}} \
expected-note {{when looking up 'end' function for range expression of type 'DeletedEnd'}}
DeletedEnd *pDE;
for (auto i : pDE) { } // expected-error {{invalid range expression of type 'DeletedEnd *'; no viable 'begin' function available}}
PrivateEnd PE;
// FIXME: This diagnostic should be improved, as it does not specify that
// the range is invalid.
for (auto i : PE) { } // expected-error{{'end' is a private member of 'PrivateEnd'}}
PrivateEnd *pPE;
for (auto i : pPE) { }// expected-error {{invalid range expression of type 'PrivateEnd *'}}
// expected-error@-1 {{'end' is a private member of 'PrivateEnd'}}
DeletedADLBegin DAB;
for (auto i : DAB) { } // expected-error {{call to deleted function 'begin'}}\
expected-note {{when looking up 'begin' function for range expression of type 'DeletedADLBegin'}}
OverloadedStar OS;
for (auto i : *OS) { }
for (auto i : OS) { } // expected-error {{invalid range expression of type 'OverloadedStar'; did you mean to dereference it with '*'?}}
for (Data *p : pt) { } // expected-error {{invalid range expression of type 'T *'; did you mean to dereference it with '*'?}}
// expected-error@-1 {{no viable conversion from 'Data' to 'Data *'}}
// expected-note@4 {{selected 'begin' function with iterator type 'Data *'}}
}