Bug Summary

File:dmake/unix/rmprq.c
Location:line 72, column 7
Description:Access to field 'cl_prq' results in a dereference of a null pointer (loaded from variable 'tlp')

Annotated Source Code

1/*
2--
3-- SYNOPSIS
4-- Remove prerequisites code.
5--
6-- DESCRIPTION
7-- This code is different for DOS and for UNIX and parallel make
8-- architectures since the parallel case requires the rm's to be
9-- run in parallel, whereas DOS guarantees to run them sequentially.
10--
11-- AUTHOR
12-- Dennis Vadura, dvadura@dmake.wticorp.com
13--
14-- WWW
15-- http://dmake.wticorp.com/
16--
17-- COPYRIGHT
18-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved.
19--
20-- This program is NOT free software; you can redistribute it and/or
21-- modify it under the terms of the Software License Agreement Provided
22-- in the file <distribution-root>/readme/license.txt.
23--
24-- LOG
25-- Use cvs log to obtain detailed change logs.
26*/
27
28#include "extern.h"
29
30PUBLIC void
31Remove_prq( tcp )/*
32===================
33 Removable targets (ie. an inferred intermediate node) are removed
34 by this function by running Make() on the special target .REMOVE
35 (pointed to by tcp).
36 As this function can be called from within another Make() (for example
37 like this:
38 Make()->Exec_commands()->Do_cmnd()->runargv()->..->_finished_child()
39 ->Update_time_stamp()->Remove_prq() )
40 it is necessary to store and restore the dynamic macros when Make()
41 is finished.
42
43 FIXME: Another potential problem is that while building .REMOVE another
44 previously started target finishes and from _finished_child() calls
45 Remove_prq() again. This will delete the dynamic macros and possibly
46 clear/reset the prerequisites of the previous .REMOVE target.
47*/
48CELLPTR tcp;
49{
50 static LINKPTR rlp = NIL(LINK)((LINK*)((void*)0));
51 static int flag = 0;
52 static HASHPTR m_at, m_q, m_b, m_g, m_l, m_bb, m_up;
53 char *m_at_s, *m_g_s, *m_q_s, *m_b_s, *m_l_s, *m_bb_s, *m_up_s;
54 LINKPTR tlp;
55
56 /* Unset F_MADE and F_VISITED. */
57 tcp->ce_flag &= ~(F_MADE0x8000|F_VISITED0x0080);
58 tcp->ce_time = 0L;
59
60 /* The idea seems to be to create a target that is used to remove
61 * intermediate prerequisites. Why add something to the "CeMeToo(tlp)"
62 * list? I don't understand this yet.
63 * FIXME! Either comment on what is going on or fix the code. */
64 for( tlp=rlp; tlp !=NIL(LINK)((LINK*)((void*)0)); tlp=tlp->cl_next )
1
Loop condition is false. Execution continues on line 70
65 /* Find first target that has F_VISITED not set or F_MADE set,
66 * i.e. it is not currently made or already done. */
67 if( (tlp->cl_prq->ce_flag & (F_VISITED0x0080|F_MADE0x8000)) != F_VISITED0x0080 )
68 break;
69
70 if( tlp == NIL(LINK)((LINK*)((void*)0)) ) {
2
Taking true branch
71 TALLOC(tlp, 1, LINK)if ((tlp = (LINK*) calloc((unsigned int)(1), (size_t)sizeof(LINK
))) == (LINK*)0) {No_ram();}
;
3
Within the expansion of the macro 'TALLOC':
a
Value assigned to 'tlp'
b
Assuming pointer value is null
72 TALLOC(tlp->cl_prq, 1, CELL)if ((tlp->cl_prq = (CELL*) calloc((unsigned int)(1), (size_t
)sizeof(CELL))) == (CELL*)0) {No_ram();}
;
4
Within the expansion of the macro 'TALLOC':
a
Access to field 'cl_prq' results in a dereference of a null pointer (loaded from variable 'tlp')
73 tlp->cl_next = rlp;
74 rlp = tlp;
75 }
76
77 *tlp->cl_prq = *tcp;
78
79 /* We save the dynamic macro values here, as it is possible that the
80 * .REMOVE recipe is getting executed for a target while some other target
81 * is in the middle of executing it's list of recipe lines, in this case
82 * the values of $@ etc, must be preserved so that when we return to
83 * complete the other recipe we must make certain that the values of it's
84 * dynamic macros are unmodified. */
85
86 if( !flag ) {
87 /* Do the getting of the macros only once. */
88 flag = 1;
89 m_at = Get_name("@", Macs, TRUE1);
90 m_g = Get_name(">", Macs, TRUE1);
91 m_q = Get_name("?", Macs, TRUE1);
92 m_b = Get_name("<", Macs, TRUE1);
93 m_l = Get_name("&", Macs, TRUE1);
94 m_bb = Get_name("*", Macs, TRUE1);
95 m_up = Get_name("^", Macs, TRUE1);
96 }
97
98 m_at_s = m_at->ht_value; m_at->ht_value = NIL(char)((char*)((void*)0));
99 m_g_s = m_g->ht_value; m_g->ht_value = NIL(char)((char*)((void*)0));
100 m_q_s = m_q->ht_value; m_q->ht_value = NIL(char)((char*)((void*)0));
101 m_b_s = m_b->ht_value; m_b->ht_value = NIL(char)((char*)((void*)0));
102 m_l_s = m_l->ht_value; m_l->ht_value = NIL(char)((char*)((void*)0));
103 m_bb_s = m_bb->ht_value; m_bb->ht_value = NIL(char)((char*)((void*)0));
104 m_up_s = m_up->ht_value; m_up->ht_value = NIL(char)((char*)((void*)0));
105
106 Make( tlp->cl_prq, tcp );
107 if( tlp->cl_prq->ce_dir ){
108 FREE(tlp->cl_prq->ce_dir)free((char*)(tlp->cl_prq->ce_dir));
109 tlp->cl_prq->ce_dir=NIL(char)((char*)((void*)0));
110 }
111
112 m_at->ht_value = m_at_s;
113 m_g->ht_value = m_g_s;
114 m_q->ht_value = m_q_s;
115 m_b->ht_value = m_b_s;
116 m_l->ht_value = m_l_s;
117 m_bb->ht_value = m_bb_s;
118 m_up->ht_value = m_up_s;
119}