1515#include "root.h"
1616#include "rmem.h"
1717
18- #include "enum.h"
19- #include "aggregate.h"
20- #include "init.h"
21- #include "attrib.h"
22- #include "scope.h"
23- #include "id.h"
24- #include "mtype.h"
25- #include "declaration.h"
2618#include "aggregate.h"
2719#include "expression.h"
2820#include "module.h"
21+ #include "scope.h"
2922
3023#define LOG 0
3124
32- /* Code to do access checks
33- */
34-
35- bool hasPackageAccess (Scope * sc , Dsymbol * s );
36- bool hasPrivateAccess (AggregateDeclaration * ad , Dsymbol * smember );
37- bool isFriendOf (AggregateDeclaration * ad , AggregateDeclaration * cd );
38-
3925/****************************************
40- * Return Prot access for Dsymbol smember in this declaration .
26+ * Check that s is a member of ad (or one of its base casses if exist) .
4127 */
42- Prot getAccess (AggregateDeclaration * ad , Dsymbol * smember )
28+ bool isMember (AggregateDeclaration * ad , Dsymbol * s )
4329{
44- Prot access_ret = Prot (PROTnone );
45-
46- #if LOG
47- printf ("+AggregateDeclaration::getAccess(this = '%s', smember = '%s')\n" ,
48- ad -> toChars (), smember -> toChars ());
49- #endif
30+ if (s -> toParent2 () == ad )
31+ return true;
5032
51- assert (ad -> isStructDeclaration () || ad -> isClassDeclaration ());
52- if (smember -> toParent () == ad )
53- {
54- access_ret = smember -> prot ();
55- }
56- else if (smember -> isDeclaration ()-> isStatic ())
57- {
58- access_ret = smember -> prot ();
59- }
6033 if (ClassDeclaration * cd = ad -> isClassDeclaration ())
6134 {
6235 for (size_t i = 0 ; i < cd -> baseclasses -> dim ; i ++ )
6336 {
6437 BaseClass * b = (* cd -> baseclasses )[i ];
65-
66- Prot access = getAccess (b -> base , smember );
67- switch (access .kind )
68- {
69- case PROTnone :
70- break ;
71-
72- case PROTprivate :
73- access_ret = Prot (PROTnone ); // private members of base class not accessible
74- break ;
75-
76- case PROTpackage :
77- case PROTprotected :
78- case PROTpublic :
79- case PROTexport :
80- // If access is to be tightened
81- if (b -> protection .isMoreRestrictiveThan (access ))
82- access = b -> protection ;
83-
84- // Pick path with loosest access
85- if (access_ret .isMoreRestrictiveThan (access ))
86- access_ret = access ;
87- break ;
88-
89- default :
90- assert (0 );
91- }
92- }
93- }
94-
95- #if LOG
96- printf ("-AggregateDeclaration::getAccess(this = '%s', smember = '%s') = %d\n" ,
97- ad -> toChars (), smember -> toChars (), access_ret );
98- #endif
99- return access_ret ;
100- }
101-
102- /********************************************************
103- * Helper function for checkAccess()
104- * Returns:
105- * false is not accessible
106- * true is accessible
107- */
108- static bool isAccessible (
109- Dsymbol * smember ,
110- Dsymbol * sfunc ,
111- AggregateDeclaration * dthis ,
112- AggregateDeclaration * cdscope )
113- {
114- assert (dthis );
115-
116- #if 0
117- printf ("isAccessible for %s.%s in function %s() in scope %s\n" ,
118- dthis -> toChars (), smember -> toChars (),
119- sfunc ? sfunc -> toChars () : "NULL" ,
120- cdscope ? cdscope -> toChars () : "NULL" );
121- #endif
122- if (hasPrivateAccess (dthis , sfunc ) ||
123- isFriendOf (dthis , cdscope ))
124- {
125- if (smember -> toParent () == dthis )
126- return true;
127-
128- if (ClassDeclaration * cdthis = dthis -> isClassDeclaration ())
129- {
130- for (size_t i = 0 ; i < cdthis -> baseclasses -> dim ; i ++ )
131- {
132- BaseClass * b = (* cdthis -> baseclasses )[i ];
133- Prot access = getAccess (b -> base , smember );
134- if (access .kind >= PROTprotected ||
135- isAccessible (smember , sfunc , b -> base , cdscope ))
136- {
137- return true;
138- }
139- }
140- }
141- }
142- else
143- {
144- if (smember -> toParent () != dthis )
145- {
146- if (ClassDeclaration * cdthis = dthis -> isClassDeclaration ())
147- {
148- for (size_t i = 0 ; i < cdthis -> baseclasses -> dim ; i ++ )
149- {
150- BaseClass * b = (* cdthis -> baseclasses )[i ];
151- if (isAccessible (smember , sfunc , b -> base , cdscope ))
152- return true;
153- }
154- }
38+ if (isMember (b -> base , s ))
39+ return true;
15540 }
15641 }
15742 return false;
15843}
15944
160- /*******************************
161- * Do access check for member of this class, this class being the
162- * type of the 'this' pointer used to access smember.
163- * Returns true if the member is not accessible.
164- */
165- bool checkAccess (AggregateDeclaration * ad , Loc loc , Scope * sc , Dsymbol * smember )
166- {
167- FuncDeclaration * f = sc -> func ;
168- AggregateDeclaration * cdscope = sc -> getStructClassScope ();
169-
170- #if LOG
171- printf ("AggregateDeclaration::checkAccess() for %s.%s in function %s() in scope %s\n" ,
172- ad -> toChars (), smember -> toChars (),
173- f ? f -> toChars () : NULL ,
174- cdscope ? cdscope -> toChars () : NULL );
175- #endif
176-
177- Dsymbol * smemberparent = smember -> toParent ();
178- if (!smemberparent || !smemberparent -> isAggregateDeclaration ())
179- {
180- #if LOG
181- printf ("not an aggregate member\n" );
182- #endif
183- return false; // then it is accessible
184- }
185-
186- // BUG: should enable this check
187- //assert(smember->parent->isBaseOf(this, NULL));
188-
189- bool result ;
190- Prot access ;
191- if (smemberparent == ad )
192- {
193- access = smember -> prot ();
194- result = access .kind >= PROTpublic ||
195- hasPrivateAccess (ad , f ) ||
196- isFriendOf (ad , cdscope ) ||
197- (access .kind == PROTpackage && hasPackageAccess (sc , smember )) ||
198- ad -> getAccessModule () == sc -> module ;
199- #if LOG
200- printf ("result1 = %d\n" , result );
201- #endif
202- }
203- else if ((access = getAccess (ad , smember )).kind >= PROTpublic )
204- {
205- result = true;
206- #if LOG
207- printf ("result2 = %d\n" , result );
208- #endif
209- }
210- else if (access .kind == PROTpackage && hasPackageAccess (sc , ad ))
211- {
212- result = true;
213- #if LOG
214- printf ("result3 = %d\n" , result );
215- #endif
216- }
217- else
218- {
219- result = isAccessible (smember , f , ad , cdscope );
220- #if LOG
221- printf ("result4 = %d\n" , result );
222- #endif
223- }
224- if (!result )
225- {
226- ad -> error (loc , "member %s is not accessible" , smember -> toChars ());
227- //printf("smember = %s %s, prot = %d, semanticRun = %d\n",
228- // smember->kind(), smember->toPrettyChars(), smember->prot(), smember->semanticRun);
229- return true;
230- }
231- return false;
232- }
233-
23445/****************************************
235- * Determine if this is the same or friend of cd .
46+ * Determine if scope sc has protection access to s .
23647 */
237- bool isFriendOf ( AggregateDeclaration * ad , AggregateDeclaration * cd )
48+ bool hasProtectedAccess ( Scope * sc , Dsymbol * s )
23849{
239- #if LOG
240- printf ("AggregateDeclaration::isFriendOf(this = '%s', cd = '%s')\n" , ad -> toChars (), cd ? cd -> toChars () : "null" );
241- #endif
242- if (ad == cd )
243- return true;
244-
245- // Friends if both are in the same module
246- //if (toParent() == cd->toParent())
247- if (cd && ad -> getAccessModule () == cd -> getAccessModule ())
50+ for (Scope * scx = sc ; scx ; scx = scx -> enclosing )
24851 {
249- #if LOG
250- printf ("\tin same module\n" );
251- #endif
252- return true;
253- }
52+ if (!scx -> scopesym )
53+ continue ;
25454
255- #if LOG
256- printf ("\tnot friend\n" );
257- #endif
55+ AggregateDeclaration * ad = scx -> scopesym -> isClassDeclaration ();
56+ if (ad && isMember (ad , s ))
57+ return true;
58+ }
25859 return false;
25960}
26061
@@ -335,61 +136,6 @@ bool hasPackageAccess(Scope *sc, Dsymbol *s)
335136 return false;
336137}
337138
338- /**********************************
339- * Determine if smember has access to private members of this declaration.
340- */
341- bool hasPrivateAccess (AggregateDeclaration * ad , Dsymbol * smember )
342- {
343- if (smember )
344- {
345- AggregateDeclaration * cd = NULL ;
346- Dsymbol * smemberparent = smember -> toParent ();
347- if (smemberparent )
348- cd = smemberparent -> isAggregateDeclaration ();
349-
350- #if LOG
351- printf ("AggregateDeclaration::hasPrivateAccess(class %s, member %s)\n" ,
352- ad -> toChars (), smember -> toChars ());
353- #endif
354-
355- if (ad == cd ) // smember is a member of this class
356- {
357- #if LOG
358- printf ("\tyes 1\n" );
359- #endif
360- return true; // so we get private access
361- }
362-
363- // If both are members of the same module, grant access
364- while (1 )
365- {
366- Dsymbol * sp = smember -> toParent ();
367- if (sp -> isFuncDeclaration () && smember -> isFuncDeclaration ())
368- smember = sp ;
369- else
370- break ;
371- }
372- if (!cd && ad -> toParent () == smember -> toParent ())
373- {
374- #if LOG
375- printf ("\tyes 2\n" );
376- #endif
377- return true;
378- }
379- if (!cd && ad -> getAccessModule () == smember -> getAccessModule ())
380- {
381- #if LOG
382- printf ("\tyes 3\n" );
383- #endif
384- return true;
385- }
386- }
387- #if LOG
388- printf ("\tno\n" );
389- #endif
390- return false;
391- }
392-
393139/****************************************
394140 * Check access to d for expression e.d
395141 * Returns true if the declaration is not accessible.
@@ -398,50 +144,30 @@ bool checkAccess(Loc loc, Scope *sc, Expression *e, Declaration *d)
398144{
399145 if (sc -> flags & SCOPEnoaccesscheck )
400146 return false;
147+ if (d -> isUnitTestDeclaration ()) // Unittests are always accessible.
148+ return false;
401149
402150#if LOG
403- if (e )
404- {
405- printf ("checkAccess(%s . %s)\n" , e -> toChars (), d -> toChars ());
406- printf ("\te->type = %s\n" , e -> type -> toChars ());
407- }
408- else
409- {
410- printf ("checkAccess(%s)\n" , d -> toPrettyChars ());
411- }
151+ printf ("[%s] checkAccess(%s)\n" , loc .toChars (), d -> toPrettyChars ());
412152#endif
413- if ( d -> isUnitTestDeclaration ())
414- {
415- // Unittests are always accessible.
153+
154+ // friend access
155+ if ( d -> getAccessModule () == sc -> module )
416156 return false;
417- }
418- if (!e )
157+
158+ // check access rights
159+ if (d -> prot ().kind == PROTprivate ||
160+ d -> prot ().kind == PROTpackage && !hasPackageAccess (sc , d ) ||
161+ d -> prot ().kind == PROTprotected && !hasProtectedAccess (sc , d ))
419162 {
420- if (d -> prot ().kind == PROTprivate && d -> getAccessModule () != sc -> module ||
421- d -> prot ().kind == PROTpackage && !hasPackageAccess (sc , d ))
422- {
163+ AggregateDeclaration * ad = d -> toParent2 ()-> isAggregateDeclaration ();
164+ if (ad )
165+ ad -> error (loc , "member %s is not accessible from module %s" ,
166+ d -> toChars (), sc -> module -> toChars ());
167+ else
423168 error (loc , "%s %s is not accessible from module %s" ,
424169 d -> kind (), d -> toPrettyChars (), sc -> module -> toChars ());
425- return true;
426- }
427- }
428- else if (e -> type -> ty == Tclass )
429- {
430- // Do access check
431- ClassDeclaration * cd = (ClassDeclaration * )(((TypeClass * )e -> type )-> sym );
432- if (e -> op == TOKsuper )
433- {
434- ClassDeclaration * cd2 = sc -> func -> toParent ()-> isClassDeclaration ();
435- if (cd2 )
436- cd = cd2 ;
437- }
438- return checkAccess (cd , loc , sc , d );
439- }
440- else if (e -> type -> ty == Tstruct )
441- {
442- // Do access check
443- StructDeclaration * cd = (StructDeclaration * )(((TypeStruct * )e -> type )-> sym );
444- return checkAccess (cd , loc , sc , d );
170+ return true;
445171 }
446172 return false;
447173}
0 commit comments